patternpythonMinor
Testing Out Testing
Viewed 0 times
testingoutstackoverflow
Problem
I've been learning about unit testing with pytest recently, trying to figure out what is and isn't a valuable thing to test. I'm very new to it, so I thought a review would be a good way to learn about holes I'm leaving and mistakes I'm making.
So, I'm primarily interested in the test functions being reviewed, though I'm open to feedback on the functions being tested too.
The
Note: Shotgun is a third party service I often hook into. A Shotgun object is just a tool for calling queries and doing updates on an external database. For these purposes, you mostly just need to know that it's an object that needs to authenticate.
I tried to focus my testing on things that could be broken by changes, or are likely to go wrong without immediately being noticed. So here's the scripts:
test_tools.py
```
import pytest
import os
from time import sleep
from tools import get_shotgun, create_folder, ProgressBar
@pytest.fixture(scope='module')
def shotgun():
return get_shotgun()
def test_get_shotgun_returns_value(shotgun):
assert shotgun is not None, "Shotgun object was not returned"
def test_get_shotgun_credentials(shotgun):
shotgun.find_one("Project", [])
def test_create_folder_invalid_path_raises_errors():
with pytest.raises(OSError):
create_folder("\\\\\\")
def test_create_folder_swallow_existing_folder_exception():
# Folder of current file definitely exists.
folder = os.path.dirname(__file__)
create_folder(folder)
def test_create_folder_returns_original_path():
folder = "dummy"
while os.path.isdir(folder):
folder = folder + '_'
assert folder == create_folder(folder), "Original path was not returned"
try:
os.rmdir(folder)
So, I'm primarily interested in the test functions being reviewed, though I'm open to feedback on the functions being tested too.
The
tools.py functions are just common functions I often need across my scripts, so I wanted to collect them in the library for convenience. A progress bar for giving feedback on how far along a loop has run, a function to ensure that a folder exists and a quick connection function.Note: Shotgun is a third party service I often hook into. A Shotgun object is just a tool for calling queries and doing updates on an external database. For these purposes, you mostly just need to know that it's an object that needs to authenticate.
I tried to focus my testing on things that could be broken by changes, or are likely to go wrong without immediately being noticed. So here's the scripts:
test_tools.py
```
import pytest
import os
from time import sleep
from tools import get_shotgun, create_folder, ProgressBar
@pytest.fixture(scope='module')
def shotgun():
return get_shotgun()
def test_get_shotgun_returns_value(shotgun):
assert shotgun is not None, "Shotgun object was not returned"
def test_get_shotgun_credentials(shotgun):
shotgun.find_one("Project", [])
def test_create_folder_invalid_path_raises_errors():
with pytest.raises(OSError):
create_folder("\\\\\\")
def test_create_folder_swallow_existing_folder_exception():
# Folder of current file definitely exists.
folder = os.path.dirname(__file__)
create_folder(folder)
def test_create_folder_returns_original_path():
folder = "dummy"
while os.path.isdir(folder):
folder = folder + '_'
assert folder == create_folder(folder), "Original path was not returned"
try:
os.rmdir(folder)
Solution
I often refactor my tests based on what I already written and at the beginning I start with tests like yours:
After time though, I almost always delete those trivial cases, because every other test will fail if tested object is not created. This tests don't carry much value with them and also test are often run in random order, so that's another argument why this is not very useful.
I would also have test_fixture for every test with directories to "purge" temporaries from previous runs, so you're ALWAYS sure that you have same conditions
Names of your tests aren't the greatest - I don't know what they mean.
ProgressBar tests - you always do the same thing at the beginning of the test - extract it.
One more thing - do they test something? I don't have Shotgun installed, but I think that tampering with arguments of functions wouldn't do much.
You don't have any assertions in your ProgressBar tests - this doesn't feel right. Maybe you should return string and check it with some kind of prepared string?
And I think the most important thing I've learned is this - make variable names meaningful. Is ProgressBar(100) somehow different than ProgressBar(10)? If it is the case, then call them differently. Is 0.1 some kind of special interval? Assign it to a variable and make reader sure.
And one last thing - please don't use if's in UTs. It is hard enough to follow code logic and making ifs in unit tests can be painful.
def test_get_shotgun_returns_value(shotgun):After time though, I almost always delete those trivial cases, because every other test will fail if tested object is not created. This tests don't carry much value with them and also test are often run in random order, so that's another argument why this is not very useful.
I would also have test_fixture for every test with directories to "purge" temporaries from previous runs, so you're ALWAYS sure that you have same conditions
Names of your tests aren't the greatest - I don't know what they mean.
ProgressBar tests - you always do the same thing at the beginning of the test - extract it.
One more thing - do they test something? I don't have Shotgun installed, but I think that tampering with arguments of functions wouldn't do much.
You don't have any assertions in your ProgressBar tests - this doesn't feel right. Maybe you should return string and check it with some kind of prepared string?
And I think the most important thing I've learned is this - make variable names meaningful. Is ProgressBar(100) somehow different than ProgressBar(10)? If it is the case, then call them differently. Is 0.1 some kind of special interval? Assign it to a variable and make reader sure.
And one last thing - please don't use if's in UTs. It is hard enough to follow code logic and making ifs in unit tests can be painful.
Code Snippets
def test_get_shotgun_returns_value(shotgun):Context
StackExchange Code Review Q#138327, answer score: 5
Revisions (0)
No revisions yet.