Jason Yu
Jason Yu

Reputation: 131

AssertError not catched in unittest in python try-except clause

I have a object created in a test case, and want to make test inside of its method. But the exception is swallow by the try-except clause. I know I can change raise the exception in run but it is not what I want. Is there a way that any unittest tool can handle this?

It seems that assertTrue method of unittest.TestCase is just a trivial assert clause.

class TestDemo(unittest.TestCase):

    def test_a(self):

        test_case = self

        class NestedProc:

            def method1(self):
                print("flag show the method is running")
                test_case.assertTrue(False)

            def run(self):
                try:
                    self.method1()
                except:
                    pass  # can raise here to give the exception but not what I want.

        NestedProc().run() # no exception raised
        # NestedProc().method1() # exception raised

EDIT

For clarity, I paste my realworld test case here. The most tricky thing here is that ParentProcess will always success leading to AssertError not correctly being propagated to test function.

class TestProcess(unittest.TestCase);

    @pytest.mark.asyncio
    async def test_process_stack_multiple(self):
        """
        Run multiple and nested processes to make sure the process stack is always correct
        """
        expect_true = []

        def test_nested(process):
            expect_true.append(process == Process.current())

        class StackTest(plumpy.Process):

            def run(self):
                # TODO: unexpected behaviour here
                # if assert error happend here not raise
                # it will be handled by try except clause in process
                # is there better way to handle this?
                expect_true.append(self == Process.current())
                test_nested(self)

        class ParentProcess(plumpy.Process):

            def run(self):
                expect_true.append(self == Process.current())
                proc = StackTest()
                # launch the inner process
                asyncio.ensure_future(proc.step_until_terminated())

        to_run = []
        for _ in range(100):
            proc = ParentProcess()
            to_run.append(proc)

        await asyncio.gather(*[p.step_until_terminated() for p in to_run])
        for proc in to_run:
            self.assertEqual(plumpy.ProcessState.FINISHED, proc.state)

        for res in expect_true:
            self.assertTrue(res)

Upvotes: 1

Views: 547

Answers (1)

deceze
deceze

Reputation: 522402

Any assert* method and even fail() just raises an exception. The easiest method is probably to manually set a flag and fail() afterwards:

def test_a(self):
    success = True

    class NestedProc:
       def method1(self):
           nonlocal success
           success = False
           raise Exception()

       ...

    NestedProc().run()

    if not success:
        self.fail()

Upvotes: 2

Related Questions