Pytestの使い方
Pytestを使ってみたかったので,使ってみた
Pytestの使い方
今まで研究で実験を行っている中で,テストコードを書いたことがなく,インターンを通じてテストコードの重要を思い知らされたので,これを機に使えるようになっておきたい.
書き方
適当に四則演算をする関数をoperation.pyに用意する.
1
2
3
4
5
6
7
8
9
10
11
12
def add(a, b):
return a + b
def sub(a, b):
return a - b
def mul(a, b):
return a * b
def div(a, b):
assert b != 0, "b must not be 0!!"
return a / b
これに対するテストコードをtest_operation.pyに以下のように書く.
1
2
3
4
5
6
7
from operations import add, div, mul, sub
def test_operations():
assert add(1, 2) == 3
assert sub(1, 2) == -1
assert mul(1, 2) == 2
assert div(1, 2) == 0.5
pytestでは,test_で始まるファイル・関数をテストケースとして認識して実行する. それぞれに対して上記のような結果が得られるか実行すると,以下のように表示される.
1
2
3
4
5
6
7
8
9
hogehoge@hogehoge ~ % pytest
======================================================================================================================== test session starts ========================================================================================================================
platform darwin -- Python 3.11.7, pytest-8.0.1, pluggy-1.4.0
plugins: anyio-4.2.0
collected 1 items
test/test_operations.py .
========================================================================================================================= 1 passed in 3.51s =========================================================================================================================
このようにpassedになっていれば,正しく実行されている. ただassertを書くだけでテストが実行できるのであれば結構便利だと思う.
試しにSelf-Attentionのコードもテストしてみた.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MultiHeadAttention(nn.Module):
def __init__(self, dim: int, nhead: int) -> None:
super(MultiHeadAttention, self).__init__()
self.W_q = nn.Parameter(torch.randn(nhead, dim, dim // nhead))
self.W_k = nn.Parameter(torch.randn(nhead, dim, dim // nhead))
self.W_v = nn.Parameter(torch.randn(nhead, dim, dim // nhead))
self.softmax = nn.Softmax(dim=-1)
self.scaler = 1 / math.sqrt(dim)
self.linear = nn.Linear(dim, dim)
self.nhead = nhead
def forward(self, x_: Tensor) -> Tensor:
B, L, D = x_.shape
x = x_.repeat(self.nhead, 1, 1, 1).permute(1, 0, 2, 3)
q = torch.einsum("bhld,hdk->bhlk", x, self.W_q)
k = torch.einsum("bhld,hdk->bhlk", x, self.W_k)
v = torch.einsum("bhld,hdk->bhlk", x, self.W_v)
attn_weight = self.softmax(torch.einsum("bhld,bhkd->bhlk", q, k) * self.scaler)
qkv = torch.einsum("bhlk,bhkd->bhld", attn_weight, v)
out = self.linear(qkv.view(B, L, D))
return out
テストコードをtest_mha.pyとして
1
2
3
4
5
from MultiHeadAttention import MultiHeadAttention
def test_MultiHeadAttention():
mla = MultiHeadAttention(64, 8)
assert mla(torch.randn(16, 32, 64)).shape == (16, 32, 64)
これを実行すると,
1
2
3
4
5
6
7
8
9
hogehoge@hogehoge ~ % pytest
======================================================================================================================== test session starts ========================================================================================================================
platform darwin -- Python 3.11.7, pytest-8.0.1, pluggy-1.4.0
plugins: anyio-4.2.0
collected 1 items
test/test_mha.py .
========================================================================================================================= 1 passed in 3.51s =========================================================================================================================
上手く行ってる.
おわりに
今回はpytestを使ったテストコードの書き方をまとめてみた.今後はこれを使って研究開発していきたい
This post is licensed under CC BY 4.0 by the author.