TheRealFakeNews
TheRealFakeNews

Reputation: 8183

Pytest not collecting tests with pytest command

I have in my Project/tests/learn_pytest.py a basic test. This is everything in the file:

import pytest
import os

class Learning(tmpdir):
    def create_file(self):
        p = tmpdir.mkdir("sub").join("hello.txt")
        p.write("content")
        print tmpdir.listdir()
        assert p.read() == "content"
        assert len(tmpdir.listdir()) == 1
        assert 0

On the command line, whether I am in Project or cd in to tests, when I run pytest, it outputs "collected 0 items". If I'm in the tests directory and do pytest -q learn_pytest.py the same thing happens. What am I missing here?

Upvotes: 3

Views: 10173

Answers (4)

Ouss
Ouss

Reputation: 3895

What you are missing is maybe some background on how pytest search and find tests to run, what is known as "test discovery".

For a short answer, rename the file to test_learn_pytest.py, rename the class to: class TestLearning(tmpdir): and rename the function to: def test_create_file

In pytest there the convention for naming functions and classes to be discovered by pytest. The convention is covered here: https://docs.pytest.org/en/6.2.x/goodpractices.html#test-discovery

And it can be summerized and i am quoting, with some modification, from the documentation:

begin of quote==>

  • If no arguments are specified then collection (of tests) starts from testpaths (if configured) or the current directory (like in your case). Alternatively, command line arguments can be used in any combination of directories, file names or node ids.

  • Recurse into directories, unless they match norecursedirs (which is "" by default)

  • In those directories, search for test_*.py files or *_test.py files, imported by their test package name.

  • From those files, collect test items:

    • "test" prefixed test functions or methods outside of class

    • "test" prefixed test functions or methods inside "Test" prefixed test classes (without an __init__ method)

<==end of quote

This is the default but it can be easily changed using a configuration file pytest.ini at the project root with the following content... please note that pytest looks for pytest.ini by default:

# pytest.ini
[pytest]
# test discovery
python_files = test_* # all python files that starts with test_
python_classes = Test* # all python classes that starts with Test
python_functions = test_* # all python functions that starts with test_

# do not search for tests recursively in these folders (space or newline separated)
# norecursedirs = venv virtualenv

# search only in these folders (uncomment if you really want that)
# testpaths =
#    unit
#    functional
#    integration

you can read more on customizing the behavior of pytest using the ini file here: https://docs.pytest.org/en/6.2.x/customize.html

Finally, it is helpful also make use of "pytest.mark" decorators. They will make your life easier and help you on the long run. Read more about them here: https://docs.pytest.org/en/6.2.x/example/markers.html#marking-test-functions-and-selecting-them-for-a-run

Upvotes: 2

MeharunNisa
MeharunNisa

Reputation: 11

Change the class name Learning to TestLearning and function name create_file to test_create_file, it worked in my case.

Upvotes: 1

gst
gst

Reputation: 440

Here it is :

file test_learn_pytest.py :


def test_create_file(tmpdir):  # tmpdir is a fixture and must be a function parameter
    assert 0, "now that will fail ; change the body to what you want"


Upvotes: 0

gst
gst

Reputation: 440

your module (learn_pytest.py) and method (create_file) must conform to pytest default naming convention (which is: test files and functions must be test_ prefixed)

So, rename the file to test_learn.py for instance and the method to test_create_file

greg@canon:~/tmp/54486852$ echo "def foo(): assert 0" > foo.py
greg@canon:~/tmp/54486852$ pytest -v
=============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.6.7, pytest-4.0.0, py-1.7.0, pluggy-0.8.0 -- /usr/bin/python3.6
cachedir: .pytest_cache
rootdir: /home/greg/tmp/54486852, inifile:
plugins: devpi-server-4.7.1
collected 0 items                                                                                                                                                                                                 

========================================================================================== no tests ran in 0.00 seconds ===========================================================================================
greg@canon:~/tmp/54486852$ echo "def test_foo(): assert 0" > test_foo.py

greg@canon:~/tmp/54486852$ pytest -v --collect-only
=============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.6.7, pytest-4.0.0, py-1.7.0, pluggy-0.8.0 -- /usr/bin/python3.6
cachedir: .pytest_cache
rootdir: /home/greg/tmp/54486852, inifile:
plugins: devpi-server-4.7.1
collected 1 item                                                                                                                                                                                                  
<Module 'test_foo.py'>
  <Function 'test_foo'>

=============================================================================================
greg@canon:~/tmp/54486852$ 

Upvotes: 1

Related Questions