More Related Content Similar to ソフトウェア工学2023 11 テスト Similar to ソフトウェア工学2023 11 テスト (20) More from Toru Tamaki (20) ソフトウェア工学2023 11 テスト3. テストとデバッグ
nデバッグ
• コーディングしても
• コンパイルが通らない
• Syntax error
• 実行できない
• 実行時エラー
• Segmentation fault
• Core dump
• 期待した動きをしない
• コードをデバッグする
• 経験と勘を頼りに
nテスト
• コーディングが終わってコードを
実行する
• 実行結果が仕様と一致しているこ
とを確認する
• 異なる場合にはコードを修正す
る
• すべてのモジュールをテストする
• 網羅的に行う
• 系統立てて行う
• 上位モジュールから下位モ
ジュールまですべて
4. テストとは
n テスト
• 誤りを発見すること
• 誤りが発見されたらテストの意義があ
る
• テストケースを作成する
• ある入力に対して期待する出力
• モジュールの出力が,期待出力に
一致する=テストは成功(テスト
をパスする)
• 出力が期待するものと違うなら誤
り
• 網羅的,体系的に行う
• 勘やなんとなくではダメ
n テスト専門の資格もあるほど
• JSTQB(Japan Software Testing
Qualifications Board,ソフトウェアテ
スト資格認定委員会)
• 国際ソフトウェアテスト資格
Advanced Level (AL) シラバス, 2012
• ALテストマネージャ,ALテストア
ナリスト,ALテクニカルテストア
ナリスト
• 国際ソフトウェアテスト資格
Foundation Level (FL) シラバス, 2012
• FLテスト技術者
6. 各テスト工程
n 単体テスト(ユニットテスト)
• 1つのモジュールのテスト
• xUnitなどのテストフレームワークを
用いて自動化する
n 結合テスト
• 複数のモジュールを結合して行うテス
ト
n システムテスト
• システム全体として問題なく動作する
かのテスト
• ベンダ側でダミーデータを用いて行う
• 性能テスト,ストレステストや負荷テ
スト,機能テストなども行う
n 受け入れテスト
• クライアントの要求を満たすかどうか
のテスト
• クライアントへの納品も兼ねる場
合がある
• 実際の現場で実際のデータに対してテ
ストする
• 運用テスト,要件テストなどとも言う
場合がある
8. docker composeを利用する
起動する
$ cd 09_01_add_mult
$ docker compose build
$ docker compose up -d
確認する
$ docker compose ps
停止する
$ docker compose down
10. assert:お手軽なテスト方法
n assert文
• 与えた条件を満たさなければ終了
• エラーメッセージも表示
• assert:「断言する」という意味
• 各種言語に存在
n メリット
• 簡単
• 用途多数
• 関数の引数の確認などにも
n デメリット
• いちいち停止してしまう
• 何度もテストを実行するのには向かない
assert文
満たされるべき
条件式
条件式がfalseの
ときに表示され
るメッセージ
和を計算する
自作myadd
assert 3 == myadd(1, 2), '1+2 is not 3'
12. import argparse
from compute import myadd
def main():
parser = argparse.ArgumentParser(description='add or multiply two numbers')
parser.add_argument('arg1', type=int,
help='first argment')
parser.add_argument('arg2', type=int,
help='second argment')
parser.add_argument('arg3', choices=['add', 'mult'],
help='add or mult (default: add)')
args = parser.parse_args()
a = args.arg1
b = args.arg2
c = args.arg3
print(a, b, c)
print(myadd(1, 2))
if __name__ == '__main__':
main()
assertを用いたテストコードの例
通常のmyaddを使うコード
main.py
myadd用のテストコード
assert_add.py
ここで自作関数
myaddを使う
myaddをイン
ポート
今は関係のないコード
myaddのテストケース
2種類
myaddをイン
ポート
まだダミー
自作関数はcompute.py
from compute import myadd
def main():
assert 3 == myadd(1, 2), '1+2 is not 3'
assert -2 == myadd(4, -6), '4+(-6) is not -2'
if __name__ == '__main__':
main()
def myadd(a, b):
return 0
15. TDD:テスト駆動開発
n通常の開発
• 実際のコードを書く
• それからテストコードを書く
• そしてテストを実行する
nTDD (Test-Driven Development)
• 実際のコードは詳しく書かずに作
成(ダミー)
• テストコードを書く
• テストを実行する
• 最初はダミーなのでテストは失
敗する
• テストを成功させるように実際の
コードを書く
• テストが失敗しないとコードを
書かない
• 成功したらテストコードを更新
する
Lifecycle of the Test-Driven Development methodXarawn - Own work
CC BY-SA 4.0
21. import unittest
from compute import myadd
class TestMyCompute(unittest.TestCase):
def test_myadd1(self):
val = myadd(1, 2)
self.assertEqual(3, val)
def test_myadd2(self):
val = myadd(4, 2)
self.assertEqual(6, val)
if __name__ == "__main__":
unittest.main()
テストコードの作成
n テストコードのファ
イル名はtest_add.py
必ずこのクラスから派生すること
和を計算する
自作myadd
クラス名は
分かりやすく
テストケースはメ
ソッド(名前は分
かりやすく) valが3に等
しいとい
うassert
n自作関数はcompute.py まだ
ダミー
unittestを
実行する
2つ目のテス
トケース
valが6に等
しいとい
うassert
注意:メソッド名は
小文字の「test」で始
まるものだけ!(そ
うでないとテストさ
れない)
def myadd(a, b):
return 0
22. $ docker compose exec mypython python -m test_add
FF
======================================================================
FAIL: test_myadd1 (__main__.TestMyCompute)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 9, in test_myadd1
self.assertEqual(3, val)
AssertionError: 3 != 0
======================================================================
FAIL: test_myadd2 (__main__.TestMyCompute)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 13, in test_myadd2
self.assertEqual(6, val)
AssertionError: 6 != 0
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=2)
$
テストの実行1
ダミーコード
なので失敗する
失敗したテストの数
実行したテストの
数と実行時間
実行するテストの
ファイル名から.pyを除いた
もの(-mはモジュールを実
行するという意味)
23. $ docker compose exec mypython python -m unittest test_add.py
FF
======================================================================
FAIL: test_myadd1 (test_add.TestMyCompute)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 9, in test_myadd1
self.assertEqual(3, val)
AssertionError: 3 != 0
======================================================================
FAIL: test_myadd2 (test_add.TestMyCompute)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 13, in test_myadd2
self.assertEqual(6, val)
AssertionError: 6 != 0
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=2)
$
テストの実行2
実行するテストの
ファイル名
ダミーコード
なので失敗する
失敗したテストの数
実行したテストの
数と実行時間
28. テストを実行:失敗
nコードを書いていない
• 失敗するべき
• 失敗したからコードを書ける
$ docker compose exec mypython python -m unittest test_add.py
FFF
======================================================================
FAIL: test_add (test_add.TestMyAdd)
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s
FAILED (failures=3)
$
30. $ docker compose exec mypython python -m unittest test_add.py
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
$
テストを実行:成功
nコードを書いた
• テストは成功するべき
• 失敗するならデバッグして修正
3つのテストケース
すべて成功
31. テストコードを追加
n追加するテストコードに対応する仕様
• aが0なら,結果a+bはb
• bが0なら,結果a+bはa
a=0の場合
b=0の場合
def test_add(self):
val = myadd(1, 2)
self.assertEqual(3, val)
def test_add_pp(self):
val = myadd(2, 6)
self.assertTrue(val > 0)
def test_add_nn(self):
val = myadd(-2, -6)
self.assertTrue(val < 0)
def test_add_a0(self):
val = myadd(0, 6)
self.assertEqual(6, val)
def test_add_b0(self):
val = myadd(2, 0)
self.assertTrue(2, val)
32. $ docker compose exec mypython python -m unittest test_add.py
.F...
======================================================================
FAIL: test_add_a0 (test_add.TestMyAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 21, in test_add_a0
self.assertEqual(6, val)
AssertionError: 6 != 0
----------------------------------------------------------------------
Ran 5 tests in 0.001s
FAILED (failures=1)
$
再度テストを実行:失敗
nコードを書いていない
• 失敗するべき
• 失敗したからコードを書ける
テストに失敗
35. テストコードを追加
n追加するテストコードに対応する仕様
• aが正,bが負なら
• a > bなら結果a+bは正
• a < bなら結果a+bは負
a > bの場合
a < bの場合
def test_add_a0(self):
val = myadd(0, 6)
self.assertEqual(6, val)
def test_add_b0(self):
val = myadd(2, 0)
self.assertTrue(2, val)
def test_add_pn_a_gt_b(self):
val = myadd(4, -1)
self.assertTrue(val > 0)
def test_add_pn_a_lt_b(self):
val = myadd(-1, 4)
self.assertTrue(val < 0)
36. 再度テストを実行:失敗
nコードを書いていない
• 失敗するべき
• 失敗したからコードを書ける
$ docker compose exec mypython python -m unittest test_add.py
....FF.
======================================================================
FAIL: test_add_pn_a_gt_b (test_add.TestMyAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 29, in test_add_pn_a_gt_b
self.assertTrue(val > 0)
AssertionError: False is not true
...
----------------------------------------------------------------------
Ran 7 tests in 0.002s
FAILED (failures=2)
$
37. テストを成功するようにコードを追加
n作成するコードに対応する仕様
• aが正,bが負なら
• a > bなら結果a+bは正
• a < bなら結果a+bは負
補足:
ここでは仕様に忠実に実
装している
(単なる和の計算だけ
ど)
def myadd(a, b):
if a > 0 and b > 0:
return a + b
if a < 0 and b < 0:
return a + b
if a == 0:
return b
if b == 0:
return a
if a > 0 and b < 0:
if a > b:
return a + b
if a < b:
return a + b
return 0
a > bの場合
a < bの場合
38. $ docker compose exec mypython python -m unittest test_add.py
.....F.
======================================================================
FAIL: test_add_pn_a_lt_b (test_add.TestMyAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/test_add.py", line 33, in test_add_pn_a_lt_b
self.assertTrue(val < 0)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 7 tests in 0.001s
FAILED (failures=1)
$
再度テストを実行:成功...あれ?
nコードを書いた
• テストは成功するべき
• 失敗するならデバッグして修正...?
a < bの場合が
失敗している
40. コードとテストコードの修正
diff --git a/test_add.py b/test_add.py
index ed754ff..a16ec50 100644
--- a/test_add.py
+++ b/test_add.py
@@ -29,7 +29,7 @@ class TestMyAdd(unittest.TestCase):
self.assertTrue(val > 0)
def test_add_pn_a_lt_b(self):
- val = myadd(-1, 4)
+ val = myadd(1, -4)
self.assertTrue(val < 0)
diff --git a/compute.py b/compute.py
index 97424a8..dc5fd2b 100644
--- a/compute.py
+++ b/compute.py
@@ -13,9 +13,9 @@ def myadd(a, b):
return a
if a > 0 and b < 0:
- if a > b:
+ if abs(a) > abs(b):
return a + b
- if a < b:
+ if abs(a) < abs(b):
return a + b
return 0
43. カバレッジとは
n ホワイトボックステストの指標
• カバレッジ
• 全体に占めるテストした部分の割
合
• 網羅性の指標
• 命令網羅(C0)
• すべての命令を1回以上実行
• 分岐網羅(C1)
• すべての分岐の真と偽をそれ
ぞれ1回以上実行
• 条件網羅(C2)
• すべての分岐の組み合わせ
(経路)を1回以上実行
n コードカバレッジ
• C0網羅率
• 実行した命令数/全命令数
• C0カバレッジ
• C1網羅率
• 実行した分岐数/全分岐数
• C1カバレッジ
• C2網羅率
• 実行した経路数/全経路数
• C2カバレッジ
45. $ docker compose exec mypython python -m unittest test_add.py
.......
----------------------------------------------------------------------
Ran 7 tests in 0.000s
OK
$ docker compose exec mypython coverage run test_add.py
.......
----------------------------------------------------------------------
Ran 7 tests in 0.000s
OK
$ ls -la .coverage
-rw-r--r-- 1 tamaki staff 53248 6 13 17:24 .coverage
$
coverageコマンドによる計測
カバレッジの実行
テストは成功している
実行するファイル
(テストコードに
限らない)
このファイル内に
計測結果が保存されている
51. $ docker compose exec mypython python -m unittest test_compute.py
..............
----------------------------------------------------------------------
Ran 14 tests in 0.002s
OK
$
テストスイートの作成とテストの実行
test_compute.pyを
用意する 各テストコードの
ファイル中のクラス
をインポート
インポートしたテス
トをすべて実行
これをテスト
すると
test_add.pyの7個+
test_mult.pyの7個=合計14
個のテストを実行
import unittest
from test_add import TestMyAdd
from test_mult import TestMyMult
if __name__ == "__main__":
unittest.main()
52. $ docker compose exec mypython coverage run test_compute.py
..............
----------------------------------------------------------------------
Ran 14 tests in 0.002s
OK
$ docker compose exec mypython coverage report
Name Stmts Miss Cover
-------------------------------------
compute.py 29 2 93%
test_add.py 26 1 96%
test_compute.py 5 0 100%
test_mult.py 26 1 96%
-------------------------------------
TOTAL 86 4 95%
$
テストスイートのカバレッジ
カバレッジも
一度に計算
test_add.pyの7個+
test_mult.pyの7個=合計14
個のテストを実行
60. 上位モジュールの仕様例
n以下は架空の内部設計の仕様
• クラス名:AddOrMult
• コンストラクタに与えるもの
• 和計算関数myadd
• 積計算関数mymult
• メソッド名:do(a, b, c)
• 引数cが文字列’add’ならa+b
を返す
• 引数cが文字列’mult’ならa*b
を返す
n前提
• myaddとmymultはまだ「実装して
いない」
• この段階でAddOrMultをテストす
る
• これは上位モジュールの「ユ
ニットテスト」
• まだ結合テストではない
• myaddとmymultが実装でき
たら結合テストを行う
n用意するもの
• myaddとmymultのスタブ
• モック(mock)とも言う
63. テストコード
実装前なの
で呼び出せ
ない
unittestの
mockを利
用
テストする
上位モ
ジュール
test_integration.py
import unittest
# from compute import myadd, mymult
from unittest.mock import MagicMock
myadd = MagicMock()
mymult = MagicMock()
from integration import AddOrMult
def is_mock(obj):
return obj.__class__.__name__ == 'MagicMock'
class TestAddOrMult(unittest.TestCase):
def test_add(self):
if is_mock(myadd):
myadd.return_value = 8
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'add')
self.assertEqual(8, val)
def test_mult(self):
if is_mock(mymult):
mymult.return_value = 12
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'mult')
self.assertEqual(12, val)
if __name__ == "__main__":
unittest.main()
import unittest
# from compute import myadd, mymult
from unittest.mock import MagicMock
myadd = MagicMock()
mymult = MagicMock()
from integration import AddOrMult
64. テストコード
準備:
mockかどうか
クラス名で判定する
関数を作っておく
test_integration.py
import unittest
# from compute import myadd, mymult
from unittest.mock import MagicMock
myadd = MagicMock()
mymult = MagicMock()
from integration import AddOrMult
def is_mock(obj):
return obj.__class__.__name__ == 'MagicMock'
class TestAddOrMult(unittest.TestCase):
def test_add(self):
if is_mock(myadd):
myadd.return_value = 8
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'add')
self.assertEqual(8, val)
def test_mult(self):
if is_mock(mymult):
mymult.return_value = 12
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'mult')
self.assertEqual(12, val)
if __name__ == "__main__":
unittest.main()
def is_mock(obj):
return obj.__class__.__name__ == 'MagicMock'
65. テストコード
mockの返
り値を8に
指定
ここは普通にユニット
テストするだけ
もしmockなら,関数myaddは未実装
なので,テスト用にここで強制的に
myaddの返り値を設定してしまう
test_integration.py
import unittest
# from compute import myadd, mymult
from unittest.mock import MagicMock
myadd = MagicMock()
mymult = MagicMock()
from integration import AddOrMult
def is_mock(obj):
return obj.__class__.__name__ == 'MagicMock'
class TestAddOrMult(unittest.TestCase):
def test_add(self):
if is_mock(myadd):
myadd.return_value = 8
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'add')
self.assertEqual(8, val)
def test_mult(self):
if is_mock(mymult):
mymult.return_value = 12
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'mult')
self.assertEqual(12, val)
if __name__ == "__main__":
unittest.main()
class TestAddOrMult(unittest.TestCase):
def test_add(self):
if is_mock(myadd):
myadd.return_value = 8
add_or_mult = AddOrMult(myadd, mymult)
val = add_or_mult.do(2, 6, 'add')
self.assertEqual(8, val)
66. $ docker compose exec mypython python -m unittest test_integration.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
$ docker compose exec mypython coverage run test_integration.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
$ docker compose exec mypython coverage report
Name Stmts Miss Cover
-----------------------------------------
integration.py 11 1 91%
test_integration.py 22 0 100%
-----------------------------------------
TOTAL 33 1 97%
$
ユニットテストの実行
テストを実
行
カバレッジ
計測
下位モ
ジュールは
使われてい
ない
68. 結合テストの実行
テストを実
行
カバレッジ
計測
下位モ
ジュールを
使っている
$ docker compose exec mypython python -m unittest test_integration.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
$ docker compose exec mypython coverage run test_integration.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
$ docker compose exec mypython coverage report
Name Stmts Miss Cover
-----------------------------------------
compute.py 29 23 21%
integration.py 11 1 91%
test_integration.py 20 2 90%
-----------------------------------------
TOTAL 60 26 57%
$
73. pytestの実行:成功
npytestにスクリプト名
を与える
• オプション「-v」:テス
トを詳しく表示
$ docker compose exec mypython pytest test_compute1.py
===================== test session starts =====================
platform linux -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0
rootdir: /mnt
collected 2 items
test_compute1.py .. [100%]
====================== 2 passed in 0.01s ======================
$ docker compose exec mypython pytest -v test_compute1.py
===================== test session starts =====================
platform linux -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0 --
/usr/local/bin/python
cachedir: .pytest_cache
rootdir: /mnt
collected 2 items
test_compute1.py::test_myadd PASSED [ 50%]
test_compute1.py::test_mymult PASSED [100%]
====================== 2 passed in 0.01s ======================
$
74. $ docker compose exec mypython pytest -v test_compute1.py
===================== test session starts =====================
rootdir: /mnt
collected 2 items
test_compute1.py::test_myadd PASSED [ 50%]
test_compute1.py::test_mymult FAILED [100%]
========================== FAILURES ===========================
_________________________ test_mymult _________________________
def test_mymult():
assert mymult(2, 6) == 12
assert mymult(2, 6) > 0
assert mymult(-2, -6) > 0
assert mymult(2, -6) < 0
assert mymult(-2, 6) < 0
assert mymult(0, 6) == 0
> assert mymult(2, 0) == 1
E assert 0 == 1
E + where 0 = mymult(2, 0)
test_compute1.py:23: AssertionError
=================== short test summary info ===================
FAILED test_compute1.py::test_mymult - assert 0 == 1
================= 1 failed, 1 passed in 0.04s =================
$
pytestの実行:失敗
n失敗すると停止
• assert文が失敗した以降
は,そのスクリプトは実
行されていない
• 他にも失敗するかもしれ
ないが,それは不明
ここでわざと
失敗させてみた
75. from compute import myadd, mymult
def test_myadd():
assert myadd(1, 2) == 3
assert myadd(2, 6) > 0
assert myadd(-2, -6) < 0
assert myadd(0, 6) == 6
assert myadd(2, 0) == 2
assert myadd(4, -1) > 0
assert myadd(1, -4) < 0
import pytest
from compute import myadd, mymult
@pytest.mark.parametrize(
("a", "b", "c"), [
(1, 2, 3),
(0, 6, 6),
(2, 0, 2),
])
def test_myadd_eq(a, b, c):
assert myadd(a, b) == c
@pytest.mark.parametrize(
("a", "b"), [
(-2, -6),
(1, -4),
])
def test_myadd_lt(a, b):
assert myadd(a, b) < 0
テストの書き方2
nテストケースを別で用
意する
• 「パラメトライズ」と
呼ぶ
• テストケースそれぞれ
でテスト関数を実行
• assertで失敗しても,
次のテストケースへテ
ストを継続する
引数を
別で記述
テスト関数内に
すべて列挙
テスト関数内には
一つのテスト
76. pytestの実行:成功
n失敗しても継続
• すべての失敗が一度に
検出できる
$ docker compose exec mypython pytest -v test_compute2.py
===================== test session starts =====================
platform linux -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0 --
/usr/local/bin/python
cachedir: .pytest_cache
rootdir: /mnt
collected 14 items
test_compute2.py::test_myadd_eq[1-2-3] PASSED [ 7%]
test_compute2.py::test_myadd_eq[0-6-6] PASSED [ 14%]
test_compute2.py::test_myadd_eq[2-0-2] PASSED [ 21%]
test_compute2.py::test_myadd_lt[-2--6] PASSED [ 28%]
test_compute2.py::test_myadd_lt[1--4] PASSED [ 35%]
test_compute2.py::test_myadd_gt[2-6] PASSED [ 42%]
test_compute2.py::test_myadd_gt[4--1] PASSED [ 50%]
test_compute2.py::test_mymult_eq[2-6-12] PASSED [ 57%]
test_compute2.py::test_mymult_eq[0-6-0] PASSED [ 64%]
test_compute2.py::test_mymult_eq[2-0-0] PASSED [ 71%]
test_compute2.py::test_mymult_lt[2--6] PASSED [ 78%]
test_compute2.py::test_mymult_lt[-2-6] PASSED [ 85%]
test_compute2.py::test_mymult_gt[2-6] PASSED [ 92%]
test_compute2.py::test_mymult_gt[-2--6] PASSED [100%]
===================== 14 passed in 0.02s ======================
$
77. $ docker compose exec mypython pytest -v test_compute2.py
===================== test session starts =====================
platform linux -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0 --
/usr/local/bin/python
cachedir: .pytest_cache
rootdir: /mnt
collected 14 items
test_compute2.py::test_myadd_eq[1-2-3] PASSED [ 7%]
test_compute2.py::test_myadd_eq[0-6-6] PASSED [ 14%]
test_compute2.py::test_myadd_eq[2-0-1] FAILED [ 21%]
test_compute2.py::test_myadd_lt[-2--6] PASSED [ 28%]
test_compute2.py::test_myadd_lt[1--4] PASSED [ 35%]
test_compute2.py::test_myadd_gt[2-6] PASSED [ 42%]
test_compute2.py::test_myadd_gt[4--1] PASSED [ 50%]
test_compute2.py::test_mymult_eq[2-6-12] PASSED [ 57%]
test_compute2.py::test_mymult_eq[0-6-0] PASSED [ 64%]
test_compute2.py::test_mymult_eq[2-0-0] PASSED [ 71%]
test_compute2.py::test_mymult_lt[2--6] PASSED [ 78%]
test_compute2.py::test_mymult_lt[-2-6] PASSED [ 85%]
test_compute2.py::test_mymult_gt[2-6] PASSED [ 92%]
test_compute2.py::test_mymult_gt[-2--6] PASSED [100%]
...
pytestの実行:失敗
n失敗しても継続
• すべての失敗が一度に
検出できる
失敗したテスト
78. ...
========================== FAILURES ===========================
____________________ test_myadd_eq[2-0-1] _____________________
a = 2, b = 0, c = 1
@pytest.mark.parametrize(
("a", "b", "c"), [
(1, 2, 3),
(0, 6, 6),
(2, 0, 1),
])
def test_myadd_eq(a, b, c):
> assert myadd(a, b) == c
E assert 2 == 1
E + where 2 = myadd(2, 0)
test_compute2.py:13: AssertionError
=================== short test summary info ===================
FAILED test_compute2.py::test_myadd_eq[2-0-1] - assert 2 == 1
================ 1 failed, 13 passed in 0.05s =================
$
pytestの実行:失敗
n失敗しても継続
• すべての失敗が一度に
検出できる
ここでわざと
失敗させてみた