想象一下,我已經在模塊foo
中實現了一個名爲Bar
的實用程序(也許是一個類),併爲它編寫了以下測試。pytest:對於同一接口的不同實現的可重用測試
test_foo.py:
from foo import Bar as Implementation
from pytest import mark
@mark.parametrize(<args>, <test data set 1>)
def test_one(<args>):
<do something with Implementation and args>
@mark.parametrize(<args>, <test data set 2>)
def test_two(<args>):
<do something else with Implementation and args>
<more such tests>
現在想象一下,在未來我希望寫在同一接口的不同實現。我想這些實現能夠重用是爲上面的測試套件編寫了測試:需要更改的唯一的東西是
- 的
Implementation
<test data set 1>
進口,<test data set 2>
等
所以我正在尋找一種方法來以可重複使用的方式編寫上述測試,這將允許接口的新實現的作者能夠通過將實現和測試數據注入到測試數據中來使用測試,而無需必須修改包含原始規範的文件的測試。
在pytest中這樣做會是一種很好的習慣用法嗎?
============================================== ======================
======================== ============================================
這裏是單元測試版本(不是很漂亮,但是)起作用。
define_tests.py:
# Single, reusable definition of tests for the interface. Authors of
# new implementations of the interface merely have to provide the test
# data, as class attributes of a class which inherits
# unittest.TestCase AND this class.
class TheTests():
def test_foo(self):
# Faking pytest.mark.parametrize by looping
for args, in_, out in self.test_foo_data:
self.assertEqual(self.Implementation(*args).foo(in_),
out)
def test_bar(self):
# Faking pytest.mark.parametrize by looping
for args, in_, out in self.test_bar_data:
self.assertEqual(self.Implementation(*args).bar(in_),
out)
v1.py:
# One implementation of the interface
class Implementation:
def __init__(self, a,b):
self.n = a+b
def foo(self, n):
return self.n + n
def bar(self, n):
return self.n - n
v1_test.py:
# Test for one implementation of the interface
from v1 import Implementation
from define_tests import TheTests
from unittest import TestCase
# Hook into testing framework by inheriting unittest.TestCase and reuse
# the tests which *each and every* implementation of the interface must
# pass, by inheritance from define_tests.TheTests
class FooTests(TestCase, TheTests):
Implementation = Implementation
test_foo_data = (((1,2), 3, 6),
((4,5), 6, 15))
test_bar_data = (((1,2), 3, 0),
((4,5), 6, 3))
任何人(庫的甚至是客戶端)撰寫的另一種實現方式此接口
- 可以重複使用的一組中
define_tests.py
- 注入自己的測試數據定義測試到測試
- 沒有修改任何原始文件
這將如何讓新實現的作者添加的測試新的參數化而不接觸包含測試定義的原始文件? – jacg 2014-10-16 15:10:58
您可以將燈具定義移動到中心位置,即更高級別的conftest.py文件。文檔在這裏:http://pytest.org/latest/fixture.html#sharing-a-fixture-across-tests-in-a-module-or-class-session 你想讓新作者不要觸摸特定的某些測試文件或測試套件中的任何內容? – 2014-10-16 20:19:09
應該可以在不修改任何現有代碼的情況下添加擴展。如果我發佈一個帶有一些符合實現和它們的測試的庫,那麼庫的客戶端應該能夠添加新的實現*和它們的測試*,而不用修改庫中隨附的任何文件。這是微不足道的,不是因爲我想通過向它們注入新數據來重用Exsting測試。將夾具移動到與庫一起提供的conftest.py中(除非我錯過了某些東西)仍然需要擴展器來更改庫中附帶的文件。 – jacg 2014-10-16 22:52:01