2010-10-12 33 views
10

Tôi đang sử dụng mô-đun unittest python để thực hiện một số thử nghiệm; tuy nhiên, nó rất lặp đi lặp lại.Làm thế nào để kiểm tra xác nhận tương tự cho số lượng lớn dữ liệu

Tôi có rất nhiều dữ liệu mà tôi muốn chạy qua cùng một thử nghiệm lặp đi lặp lại, kiểm tra xem có chính xác hay không. Tuy nhiên, tôi phải xác định một thử nghiệm cho mọi người.

Ví dụ: tôi muốn làm điều gì đó tương tự như thế này. Tôi biết tôi có thể làm điều đó bằng cách sử dụng một máy phát điện (tìm thấy nó trong một chủ đề trước đây ở đây). Nhưng có những lựa chọn thay thế, thậm chí có thể sử dụng một mô-đun thử nghiệm khác không?

Mọi đề xuất sẽ tuyệt vời.


import unittest 

class TestData(unittest.TestCase): 
    def testNumbers(self): 
     numbers = [0,11,222,33,44,555,6,77,8,9999] 
     for i in numbers: 
      self.assertEqual(i, 33) 
+0

Có gì sai với điều này? No trông tuyệt. –

+0

Về cơ bản, ngay sau khi xác nhận là đúng, nó sẽ dừng thực thi. – Mark

Trả lời

1

Trong bài khác tôi vấp accross Nose Tests Đó là phù hợp hơn cho dữ liệu hướng thử nghiệm.


class Test_data(): 
    def testNumbers(): 
     numbers = [0,11,222,33,44,555,6,77,8,9999] 
     for i in numbers: 
      yield checkNumber, num 

def checkNumber(num): 
    assert num == 33 

Mã trên thực hiện chính xác điều tương tự như bài đăng đầu tiên của tôi. Không cần nhập khẩu, chỉ cần viết một lớp python.

Bạn thực hiện các bài kiểm tra bằng cách gõ:

nosetests filename

2

Vấn đề với chạy khẳng định trong một vòng lặp là, nếu một trong các khẳng định thất bại, bạn không biết được giá trị gây ra nó (trong ví dụ của bạn, nó sẽ thất bại trên 0, nhưng bạn không biết rằng cho đến khi bạn gỡ lỗi). Mặt khác, lặp lại self.assertEqual(i, 33) là một ý tưởng thậm chí còn tồi tệ hơn, bởi vì nó giới thiệu sao chép mã.

Điều tôi làm trong bài kiểm tra là tạo một hàm nội bộ đơn giản, được đặt tên ngắn gọn bên trong bài kiểm tra và gọi nó với các đối số khác nhau. Vì vậy, chức năng của bạn sẽ trông như thế này:

import unittest 

class TestData(unittest.TestCase): 
    def testNumbers(self): 
     def eq(i): 
      self.assertEqual(i, 33) 
     eq(0) 
     eq(11) 
     eq(222) 
     eq(33) 
     eq(44) 
     eq(555) 
     ... 

Bằng cách này, khi khẳng định không cho 0, bạn ngay lập tức nhìn thấy nó trên stack trace in bởi module unittest.

+0

Tôi thấy những gì bạn đang làm. Đó là một ý tưởng hay. Nhưng lần đầu tiên nó chạm 33, nó sẽ ngừng thực hiện cho phần còn lại của mã. – Mark

+0

Nếu những gì bạn đang nói là bạn phải tạo lại thử nghiệm cho từng số, thì bạn nên tiếp tục với những gì Bill Gribble đề xuất và xây dựng động cơ một TestSuite. – DzinX

5

Bạn có thể muốn xem xét sử dụng lớp unittest.TestSuite, lớp này sẽ cho phép bạn tạo động một tập hợp các phiên bản unittest.TestCase sẽ được chạy riêng. Lớp con unittest.TestCase của bạn chỉ định nghĩa một phương thức thử nghiệm, với lớp chấp nhận một tham số xây dựng truyền vào giá trị để kiểm tra đối với cá thể cụ thể đó.

9

Mẫu mã cho giải pháp được đề xuất bởi Bill Gribble có thể trông như thế này:

import unittest 

class DataTestCase(unittest.TestCase): 
    def __init__(self, number): 
     unittest.TestCase.__init__(self, methodName='testOneNumber') 
     self.number = number 

    def testOneNumber(self): 
     self.assertEqual(self.number, 33) 

    def shortDescription(self): 
     # We need to distinguish between instances of this test case. 
     return 'DataTestCase for number %d' % self.number 


def get_test_data_suite(): 
    numbers = [0,11,222,33,44,555,6,77,8,9999] 
    return unittest.TestSuite([DataTestCase(n) for n in numbers]) 

if __name__ == '__main__': 
    testRunner = unittest.TextTestRunner() 
    testRunner.run(get_test_data_suite()) 
1

Các ddt library được xây dựng để giải quyết chính xác những gì bạn đang yêu cầu.

Ví dụ:

import ddt 
import unittest 

@ddt.ddt 
class EvalTests(unittest.TestCase): 

    @ddt.data(
      ('1', 1), 
      ('1 == 1', True), 
      ('1 == 2', False), 
      ('1 + 2', 4), ## This will fail 
    ) 
    def test_eval_expressions(self, case): 
     expr, exp_value = case 
     self.assertEqual(eval(expr), exp_value) 

Và khi bạn chạy nó, bạn sẽ có được 4 testcases thay vì chỉ một:

$ python -m unittest -v test_eval.py 
test_eval_expressions_1___1___1_ (test_eval.EvalTests) ... ok 
test_eval_expressions_2___1__1___True_ (test_eval.EvalTests) ... ok 
test_eval_expressions_3___1__2___False_ (test_eval.EvalTests) ... ok 
test_eval_expressions_4___1_2___4_ (test_eval.EvalTests) ... FAIL 

====================================================================== 
FAIL: test_eval_expressions_4___1_2___4_ (test_eval.EvalTests) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/lib/python/lib/site-packages/ddt.py", line 129, in wrapper 
    return func(self, *args, **kwargs) 
    File "/Work/test_eval.py", line 15, in test_eval_expressions 
    self.assertEqual(eval(expr), exp_value) 
AssertionError: 3 != 4 

---------------------------------------------------------------------- 
Ran 4 tests in 0.002s 

FAILED (failures=1) 

ý rằng ddt cố gắng đưa ra tên cho tạo CTV.

Install nó với pip:

pip install ddt 
0

Spin-off của this câu trả lời, mà đã không hoàn toàn công việc cho tôi. Khi tôi không xử lý số lượng dữ liệu lớn, tôi đã cần chạy các thử nghiệm giống nhau với các yếu tố đầu vào khác nhau. Các thử nghiệm sau đây đang sử dụng các phương pháp create_acreate_b mà tôi muốn tùy chỉnh.

Yêu cầu là chạy cả hai thử nghiệm với cùng một tùy chỉnh.

class Tests(unittest.TestCase): 

    def test_a_uses_b(self): 
     a = create_a() 
     b = create_b() 
     a.b = b 
     self.assertIs(b.a, a) 

    def test_b_uses_a(self): 
     a = create_a() 
     b = create_b() 
     b.a = a 
     self.assertIs(a.b, b) 

Instantiating TestSuiteTestCase bản thân mình, bỏ qua các bộ nạp kiểm tra, kết quả là một lỗi bởi vì nó dự kiến ​​một phương pháp duy nhất, gọi là runTest.

Kết quả là đây:

class Tests(unittest.TestCase): 

    def __init__(self, create_a, create_b): 
     super().__init__() 
     self.create_b = create_b 
     self.create_a = create_a 

    def test_a_uses_b(self): 
     a = self.create_a() 
     b = self.create_b() 
     a.b = b 
     self.assertIs(b.a, a) 

    def test_b_uses_a(self): 
     a = self.create_a() 
     b = self.create_b() 
     b.a = a 
     self.assertIs(a.b, b) 


class TestPair1(Tests): 
    def __init__(self): 
     super().__init__(create_a1, create_b1) 


class TestPair2(Tests): 
    def __init__(self): 
     super().__init__(create_a2, create_b2) 
Các vấn đề liên quan