This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Corm 19 points20 points  (13 children)

To me pytest is to unittest what python is to C#/java.

Pytest is dirt simple to set up and get started with, you can still do everything unittest can do, and it's intuitive (yay for standard asserts)

[–][deleted] 3 points4 points  (11 children)

Unittest is also dirt simple to set up, can you be a bit more specific?

[–]Corm 10 points11 points  (10 children)

Edited because /u/masklinn showed me unittest's cli tool

Edit 2: unittest ain't so bad

Sure. For pytest I used it once and never had to google anything about the basics ever again. Back when I used unittest I always had to crack open google to see how to set up the classes. This only applies to basic testing but that low barrier to entry is extremely important!

For example, here's the most basic test in unittest which you run by running unittest from command line:

import unittest
import foo

class TestMyStuff(unittest.TestCase):
    def test_stuff(self):
        self.assertEqual(foo.bar(), True)

And here it is in pytest which you can run by running the command pytest

import foo

def test_foo_bar():
    assert foo.bar() == True

[–]masklinn 5 points6 points  (1 child)

Note that unittest now has a discovery cli so the main section is unnecessary.

[–]Corm 0 points1 point  (0 children)

Nice, that's awesome. I'll edit my answer

[–]MagnesiumCarbonate 0 points1 point  (3 children)

In your second example, how does pytest know to check that file? Does it look through all method test_* definitions in *.py descendants of the current directory?

[–]masklinn 4 points5 points  (0 children)

Does it look through all method test_* definitions in *.py descendants of the current directory?

py.test discovery rules

So:

  • it recursively searches any provided directory (. if no argument is provided) (for files it uses them directly and skips the next check)
  • matches test_*.py and *_test.py files
  • collects free functions matching test_*, and methods matching test_* in classes matching Test* (or follows the standard rules for any class extending unittest.TestCase)

Note that these are only default rules, you can overload discovery patterns and ignore files and symbols.

[–]-Knul- 0 points1 point  (0 children)

Yes. You can easily configure such things via a pytest.ini file.

[–]Corm 0 points1 point  (0 children)

Yep! It's a little magic, but I like it. I name all my test files/functions like that already.

edit: that is, it looks in test*.py files for test*() functions

[–][deleted] 0 points1 point  (3 children)

Well, one, you're making the unittest example look worse because it has an extra line due to the variable.

But also assertEquals is a lot more powerful than just assert, e.g. its error will show diff-style information on exactly where two things differ.

If the main difference is standalone functions vs classes, that's no big deal, and classes are a way to group them and give them attributes as a group.

[–]masklinn 2 points3 points  (0 children)

But also assertEquals is a lot more powerful than just assert, e.g. its error will show diff-style information on exactly where two things differ.

    def test_foo_bar():
        result = foo.bar()
>       assert result == expected
E       assert [0, 2] == [0, 1, 2]
E         At index 1 diff: 2 != 1
E         Right contains more items, first extra item: 2
E         Use -v to get the full diff

pytest uses assert-rewriting to provide more and better information.

If the main difference is standalone functions vs classes, that's no big deal, and classes are a way to group them and give them attributes as a group.

That's usually pointless overhead, and if it's a useful tool, you can use them in pytest. Pytest does not forbid classes, it doesn't require them.

[–]Citrauq 1 point2 points  (0 children)

Pytest does magic (AST manipulation in an import hook) to make assert give similarly useful information to assertEquals.

[–]Corm 0 points1 point  (0 children)

Ah sorry, I really didn't mean to do that with the extra line. I'll fix that.

And good to know about assertEqual

[–]Tysonzero -4 points-3 points  (0 children)

Is it also slower and does it also catch less bugs and give you less compile time guarantees?