简体   繁体   中英

Run python test modules independtly

I have two different modules (test_a.py, test_b.py) with tests written using unittest.Tescase under one unique folder (tests_folder). If I run the tests of each module with:

python -m unittest tests_folder.test_a.py
python -m unittest tests_folder.test_b.py 

They all pass, but if I run the command:

python -m unittest discover tests_folder

Tests fail. I know this is happenning because of mocking, since I am mocking some classes in one module which are aleady imported in the other module which makes mocking not working. So I need to run the modules completely independet. Is there any way for doing this? Thanks!!

EDIT: I have prepared a small project for testing. With next folders:

project/
├── __init__.py
├── src
│   ├── class_A.py
│   ├── class_B.py
│   ├── class_C.py
│   └── __init__.py
└── tests
    ├── __init__.py
    ├── test_1_class_B.py
    └── test_2_class_C.py

Where class_B imports class_A and class_C imports class_A and class_B . All classes are empty clases and tests only run the __init__ method. I have added a print message at the beginning of each module to check when each one of them is entered.

When I run python -m unittest discover -v project.tests I have the next prints:

Tests for B
Module B
Module A
Tests for C

So this means that if in test_2_class_C I mock class_B.B it will not take effect since it was already imported in the tests for B and it is not imported again. This would cause all tests pass if they are run independently but they will fail with the discover command.

The tricky part with mocking (calling patch() ) is to use correct target.

It is possible to mock B in test_2_class_c.py with the code below.

Classes.

# src/class_a.py
print("Module A")


class A:
    def __init__(self):
        print(self.a())

    def a(self):
        return "A"

# src/class_b.py
from src.class_a import A

print("Module B")


class B:
    def __init__(self):
        A()
        print(self.b())

    def b(self):
        return "B"

# src/class_c.py
from src.class_a import A
from src.class_b import B


class C:
    def __init__(self):
        A()
        B()
        print("C")

Tests.

# tests/test_1_class_b.py
import unittest

from src.class_b import B

print("Tests for B")


class ClassBTestCase(unittest.TestCase):
    def test_b(self):
        print()
        B()

# tests/test_2_class_c.py
import unittest
from unittest.mock import patch

from src.class_c import C

print("Tests for C")


class ClassCTestCase(unittest.TestCase):
    def test_c(self):
        print()
        C()

    @patch("src.class_c.A.a")
    @patch("src.class_c.B.b")
    def test_c_mock_a_b(self, mock_b, mock_a):
        print()
        mock_a.return_value = "X"
        mock_b.return_value = "Y"
        C()

Output.

$ python -m unittest discover -v tests
Module A
Module B
Tests for B
Tests for C
test_b (test_1_class_b.ClassBTestCase) ... 
A
B
ok
test_c (test_2_class_c.ClassCTestCase) ... 
A
A
B
C
ok
test_c_mock_a_b (test_2_class_c.ClassCTestCase) ... 
X
X
Y
C
ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

These aren't real tests (as there are no asserts), but the printed output shows mocking is possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM