"No tests were found" when running unittest.main()

Answered

I have a test file and a main module file in which there's a function I'm testing. At the end of my test file, I have unittest.main() to run the unit tests.

When I run the test file, the console shows "No tests were found". This problem seems to go away when I:

(1) Enclose the unittest.main() inside an if __name__ == "__main__" (I sort of understand how this clause works, but it makes no sense for me in this case, when the unittest.main() module runs properly when there's an if clause, versus when there's no coditional at all), OR

(2) When I run my test program in Spyder

Therefore, this seems like an issue specific to Pycharm. As a result, what do I need to do/configure to get unittest.main run properly?

For your reference, here are the 2 files in my program; my test file returns no test as opposed to the 2 tests that I'd programmed for it.

---Main file: city_functions.py---

def print_city_country(city, country, population=""):
"""Print 'city, country' from input city and country"""
if population:
formatted_city_country = city + ", " + country + " - population " + str(population)
else:
formatted_city_country = city + ", " + country
return formatted_city_country

---Test file: test_cities.py---

import unittest
from city_functions import print_city_country


class TestCaseCityCountry(unittest.TestCase):
"""Test function city_country from city_functions module"""

def test_city_country_pair(self):
"""Test for names like Santiago, Chile without population input"""
formatted_city_country = print_city_country("Santiago", "Chile")
self.assertEqual(formatted_city_country, "Santiago, Chile")

def test_city_country_population(self):
"""Test for names like Ho Chi Minh City, Vietnam, 8400000"""
formatted_city_country_population = print_city_country("Santiago", "Chile", 8400000)
self.assertEqual(formatted_city_country_population, "Santiago, Chile - population 8400000")


unittest.main()
6 comments
Comment actions Permalink

I think I might have found a way to fix my problem, but I'm not quite sure why.

I had used Ctrl + Shift + F10 (like this tutorial showed). However, I just went back and used Alt + Shift + F10 (the generic run hotkey for Pycharm), it worked (though without the fancy Pycharm test status you see on the left of my screenshot, just the console result).

Does anyone know why there's such difference between 2 methods? And what's the best way in Pycharm to execute my test files?

I looked up Ctrl + Shift + 10 but found little reference for it, just cheatsheets saying it stands for "Run context configuration from editor", whatever that means.

0
Comment actions Permalink

Hi seismatica! I'm not sure top level

unittest.main()

makes much sense in test files. It blocks ability to run tests with:

python -m unittest test_cities

but allows

python test_cities.py

That's why you have different results running this script with Ctrl+Shift+F10 and with Alt+Shift+F10, first hotkey tries to run this script as test (with fancy PyCharm UI) with unittest command assuming your test file is a collection of test classes, it fails because you manually start unittest from the code itself which is excessive.

Second hotkey works ok because it just executes your script as Python file, so in this case it's sensible to start unittest inside the script or nothing will happen.

if __name__ == "__main__"

allows both ways to work - unittest.main() will be ignored when calling with unittest and executed when calling as pure Python script.

2
Comment actions Permalink

Wonderful answer Pateev! Your explanation helped me understand many of the questions that I have regarding this issue. So your recommendation would be to remove unittest.main() and use Ctrl + Shift + F10? I'm a beginner at programming and the use of unittest.main() I picked up from a Python textbook that I've been reading (Python Crash Course).

One more question: do you know why unittest.main() would return zero test (hence it should not be run), when the module is run as a test file (using python -m unittest test_cities.py as you mentioned)? I understand that running it this way will make the __name__ to become the module name (test_cities), hence the need to use if __name__ == "__main__" to skip the unittest.main() evaluation. However, I'm still not sure why unittest.main() would cause the problem that requires it to be turned off in this case.

0
Comment actions Permalink
So your recommendation would be to remove unittest.main() and use Ctrl + Shift + F10?

Yeap, the only case when one may want to leave this line is when one need an ability to call test file as python test_sample.py, but I'm not really sure how it can be useful. Maybe in some specific cases. Anyway at some point you are going to have a lot of test files per project so it's much more convenient to rely on external unittest to collect and run all tests.

I picked up from a Python textbook that I've been reading

I believe such syntax was used in the book just to simplify things for beginners.

I'm still not sure why unittest.main() would cause the problem that requires it to be turned off in this case.

Honestly I'm not sure. The problem is when you call python -m unittest test_cities what is happened is unittest parses test_cities to find all test classes, but at some point it faces unittest.main() top level expression and executes it spawning another unittest process. First unittest probably doesn't expect it and fails right away.

 

0
Comment actions Permalink

You rock Pavel!

0
Comment actions Permalink

I was having a similar problem and discovered that the root cause was that I named the file "test.py".

0

Please sign in to leave a comment.