This post describes a problem you may encounter when using pytest and the module and unit tests resided in different directories.
In this post I used Python 3.6.1 and VS Code 1.52.1 running on Windows 10. The module and the unit tests can be found on GitHub.
The code and the tests
fizz_buzz.py is a module which contains functions to solve the Fizzbuzz programming challenge.
""" Program to showcase different ways to solve the FizzBuzz coding challenge. Each function will Count from 1 - 100 inclusive For numbers divisible by 3, Add to the list the string fizz For numbers divisible by 5, Add to the list the string buzz For numbers divisible by both 3 and 5, Add to a list the string fizzbuzz For all other numbers add the number to the list and return it to the caller """ def fizz_buzz_using_boolean(): """The results of the mod calculations are set to booleans which makes the if statements easier to understand""" fizz_buzz_list = [] for x in range(1, 101): fizz = x % 3 == 0 buzz = x % 5 == 0 if fizz and buzz: fizz_buzz_list.append('fizzbuzz') continue elif fizz: fizz_buzz_list.append('fizz') continue elif buzz: fizz_buzz_list.append('buzz') continue else: fizz_buzz_list.append(x) return fizz_buzz_list def fizz_buzz_if_calc(): """Fizzbuzz solution with the mod operator used within the if statements""" fizz_buzz_list = [] for x in range(1, 101): if x % 3 == 0 and x % 5 == 0: fizz_buzz_list.append("fizzbuzz") continue elif x % 3 == 0: fizz_buzz_list.append("fizz") continue elif x % 5 == 0: fizz_buzz_list.append("buzz") continue else: fizz_buzz_list.append(x) return fizz_buzz_list if __name__ == "__main__": fb_list_2 = fizz_buzz_using_boolean() print(fb_list_2) fb_list_1 = fizz_buzz_if_calc() print(fb_list_1)
test_fizz_buzz.py contains the unit tests.
import pytest from fizz_buzz import fizz_buzz_if_calc, fizz_buzz_using_boolean @pytest.fixture def expected_number_of_elements(): """The fizzbuzz list will have 100 elements""" return 100 @pytest.fixture def fizzbuzz_expected_answer(): """A list of the fizzbuzz answers for 1 - 100""" fizz_buzz = [1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz', 16, 17, 'fizz', 19, 'buzz', 'fizz', 22, 23, 'fizz', 'buzz', 26, 'fizz', 28, 29, 'fizzbuzz', 31, 32, 'fizz', 34, 'buzz', 'fizz', 37, 38, 'fizz', 'buzz', 41, 'fizz', 43, 44, 'fizzbuzz', 46, 47, 'fizz', 49, 'buzz', 'fizz', 52, 53, 'fizz', 'buzz', 56, 'fizz', 58, 59, 'fizzbuzz', 61, 62, 'fizz', 64, 'buzz', 'fizz', 67, 68, 'fizz', 'buzz', 71, 'fizz', 73, 74, 'fizzbuzz', 76, 77, 'fizz', 79, 'buzz', 'fizz', 82, 83, 'fizz', 'buzz', 86, 'fizz', 88, 89, 'fizzbuzz', 91, 92, 'fizz', 94, 'buzz', 'fizz', 97, 98, 'fizz', 'buzz'] return fizz_buzz def test_fizz_buzz_if_calc_has_100_elements(expected_number_of_elements): actual = fizz_buzz_if_calc() assert len(actual) == expected_number_of_elements def test_fizz_buzz_using_boolean_has_100_elements(expected_number_of_elements): actual = fizz_buzz_using_boolean() assert len(actual) == expected_number_of_elements def test_fizz_buzz_if_calc_has_correct_items(fizzbuzz_expected_answer): actual = fizz_buzz_if_calc() assert actual == fizzbuzz_expected_answer def test_fizz_buzz_using_boolean_has_correct_items(fizzbuzz_expected_answer): actual = fizz_buzz_using_boolean() assert actual == fizzbuzz_expected_answer
When everything is in the same directory
Initially the directory structure for the application looked like this:
myapp
fizz_buzz.py
test_fizz_buzz.py
Using the test runner in VS Code, the unit tests ran successfully.

Changes to the directory structure
I wanted to change the directory structure and move the module and unit tests into their own directories. After making the changes, the directory structure looked like this:
myapp
src
fizz_buzz.py
tests
test_fizz_buzz.py
Problems
Following the directory structure change, the tests had disappeared from the test runner within VS Code:

Opening the test_fizz_buzz.py file showed the error
"unable to import 'fizz_buzz' pylint(import-error) [3, 1].
The tests worked before the directory structure change which meant it was likely that Python could no longer find the fizz_buzz module.
Solution
The following changes were made to the import section of test_fizz_buzz.py.
import pytest import sys sys.path.insert(0, './src/') from fizz_buzz import fizz_buzz_if_calc, fizz_buzz_using_boolean
On line 3 the sys module is imported, this module is then used on line 4 to add the src directory as a location for Python to check for the module.
With this change, the tests appear again in the test runner.

Categories: Python Unit Testing
oraclefrontovik
Developer
Leave a Reply