18

I made a small project called demo, with a single test in it

import unittest


class Test(unittest.TestCase):


    def testName1(self):
        self.assertEqual(5+9, 14)


if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()

However, from command line

ThinkPad-T520:~/workspacep/demo$ python -m unittest

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Why doesn't this work? In general, how can I run all unit tests from command line with a single line?

The structure of the directory is

demo
    tests
          demo_test1.py  __init__.py
5
  • 1
    Can you share directory structure of your project? Commented Aug 25, 2018 at 2:51
  • 1
    python test_demo.py Commented Aug 25, 2018 at 3:03
  • Well, for one thing, if you're executing python -m unittest, then inside your script, __name__ is NOT equal to "main". Commented Aug 25, 2018 at 4:45
  • Please see edits of original question to see directory structure. Commented Aug 25, 2018 at 16:00
  • Also, John Gordon, what do you mean? You can see the code above, it is main. Commented Aug 25, 2018 at 16:09

4 Answers 4

28

There are three gotcha's that I know of:

  1. Your tests in your TestCases need to be named test_*
  2. Your test files need to be named: test*.py (by default, you can change it with the -p flag when running the tests). e.g. test_demo1.py
  3. Your tests folder needs to have an __init__.py file in it, or else it won't be considered a valid location to import from.

So, for #1, you need to rename the test to test_name_1. And for #2, there's two options:

A - Restructure your files like this:

demo
    tests
        __init__.py
        test_demo1.py

Then run python -m unittest and it should find the test cases.

B - Just run it like: python -m unittest discover -p *test.py

Sign up to request clarification or add additional context in comments.

2 Comments

That the test cases' names need to begin with test_ is correct, but names of my test files actually needed to begin with test_ as well. The file __init__.py was not required (I'm doodling around with the unittest module and just have a single directory). When respecting these rules, the command python -m unittest worked with or without any discover options. Maybe those are recent changes, I'm on python 3.8.11.
The official documentation (docs.python.org/3/library/unittest.html#unittest-test-discovery) states that the pattern is test*.py, not test_*.py for file names (I manually checked this, too). I see no discrepancy with my answer for the rest of your comment: this situation is for test files inside a folder (needing __init__.py) and using defaults (so, don't need add discover to the command)
11

I fought with the same exact problem a while ago and I solved it by using test discovery command.

python -m unittest discover -s .

You can pass in your test file pattern as well and a whole other options https://docs.python.org/2/library/unittest.html#test-discovery

3 Comments

Isn't the default using discover even without passing it explicitly in the command?
Btw, this failed for me as well, got the same result as above, Ran 0 tests
@BaronYugovich It probably failed because the default pattern to match test files is test*.py while the test file name demo_test1.py can only be matched by "*_test*.py" Try python -m unittest discover -s . -p "*test*.py"
2

You need to pass in a list of modules.

For example, if your test file is foo.py, then you can run python -m unittest foo.

1 Comment

No, that's what I want to avoid. I want it to run all tests in a project. Assume this is a huge project with 100s of modules, I don't want to pass them explicitly.
0

For me (running tests from IntelliJ IDEA) I had to remove the class' 'Run configuration'. Earlier on I had wrongly imported the unittest as _pytest.unittest and ran the test class. Of course that didn't work.

I corrected the module import, but the 'run configuration' was still there, causing it to run as a Python script and not as 'Python tests'.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.