首页 > 解决方案 > How to test sequential operations in a python class involving class data

问题描述

Background

I have a class which performs fairly slow, complex operations on data. I want to write some tests for that class, but I'm having a hard time finding a suitable testing framework.

The class has an interface like this:

class thing():

    def __init__(self, datafile):
        data = read datafile

    def a(self):
        self.data_a = expensive(self.data)

    def b(self):
        self.data_b = expensive(self.data_a)

    def c(self):
        self.data_c = expensive(self.data_b)

    etc...

The way we use this class is we usually sequentially perform the operations and analyze the results, usually at each step, often in a jupyter notebook.

Question

How should one test the methods in a class which have this structure? Is there a framework / convention for building sequential test suites?

I tried...

Notes

I'm also looking for recommendations on a better title for this question

标签: pythonpytestpython-unittest

解决方案


Perhaps you could consider using the subtest feature in the unitest package:

import unittest

class TestExpensive(unittest.TestCase):

    def setUp(self):
        generated_data = generate(data)
        generated_data.write(somewhere)
        self.t = thing(somewhere)

    def test_abc(self):
        with self.subTest(status_code='a'):
             self.t.a()
             # Verify self.t.data_a has required properties
             self.assertTrue(True) 

        with self.subTest(status_code='b'):
             self.t.b()
             # Verify self.t.data_b has required properties
             self.assertTrue(False)

You can put all your expensive function calls in one test so that you can reuse any intermediate results over the course of the test. Moreover, if an error occurs, you will still be able to trace it back to the subtest that is causing the problem through the status_code variable:

======================================================================
FAIL: test_abc (__main__.TestExpensive) (status_code='b')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line 17, in test_abc
    self.assertTrue(False)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

推荐阅读