#unit-testing
1 messages · Page 27 of 1
Hi, has anyone come across that while running specifi tests with unit tests, the test passed, but while running all of the tests, some of them were failing?
Yep
yes
Try using pytest-randomly can help discover test interdependence and test isolation problems
Eg one of your other tests didn't clean up after itself
What if I have to use unittests library?
Because it is a part of code competition
and code checker uses unittests
so i wonder if there is anything I can do to fix that
Is the purpose of the challenge to find out why the tests fail in this way?
Nope
I have some test cases provided
And running them seperately all of them are passing
but if I run all of them at once
SOme of them are failing
You could try and find the first git commit where it started falling in this way?
hm, are you allowed to use pytest?
Nope, the code checker uses unittest
you don't have to rewrite the tests, but pytest can give you additional information
ah
It was not passing before, so probably I will need to rewrite the code
!rule 8 ? @hexed cloak?
8. Do not help with ongoing exams. When helping with homework, help people learn how to do the assignment without doing it for them.
competition == ongoing exam maybe?
I mean, i do not need to write my code
I've seen a bunch of failures like this in tests that didn't rollback the database, or a mock.patch
Or they did a manual patch
you're reusing a variable somewhere and one of the tests is checking that state
Had a good one where they left a thread running
It was because oop and because the object was not teared down, it was overwitten in the other test
That is my assumption
Thank you guys
Yeah, but probably because the name of the obejct stayed the same in each test case, it could be overwitten, as this Solution class did not have dunder init method
Kinda my mistake
?
Hi.. needed some help with my project structure
├───lib
│ ├───discord_bot
│ │ ├─── __main__.py
│ │ ├─── __init__.py
│ │ ├─── headers.py
│ │ └───cogs
│ │ └───helpers
│ │ └───Common
│ │ ├─── __init__.py
│ │ ├─── constants.py
│ │ └─── some_api.py
│ ├───resources
│ └───tests
│ ├─── __init__.py
│ └─── test_some_api.py
└───scripts
With above folder structure, I have headers.py at the discord bot folder and inside some_api.py, I have this import
from headers import InstaHeaders as headers
How would I re-write that import so that it doesn't fail in my test file?
from discord_bot.headers import InstaHeaders as headers
you also need cogs/__init__.py and cogs/helpers/__init__.py
I have a project with decent unit tests, but pretty much no testing on the edge, the endpoints and stuff. Any tips on where to start?
Selenium is the most developed web driver controller with the support for the most amount of browsers including edge
if by edge you mean Microsoft Edge
if by edge u mean integration testing... than in my opinion it is almost no different than writing unit tests
same pytest library (+ framework specific testing library / or requests library if nothing else ) is more than enough to do that
we write in same way to check those endpoints, in some cases we mock them usually when they are third party dependency
I prefer to be not mocking endpoints which belong to my backend services.
Ah, and the most important part.
when testing ednpoints stuff between your own microservices
that's where CI/CD stuff shines the best (like Gitlab CI)
when u set with some Infrastructure Provisioning like Terraform automatically to buy/set everything in cloud provider, and to install your services with some Configuration Management like Ansible + Docker for containrization
when everything is deployed automatically with CI/CD to run unit tests, deploy to staging environment and then to apply integration tests... that's the best / easiest / the least consuming way to handle it
no, by "the edge" I don't mean Microsoft Edge 
so the problem with having no integration tests is that the tests don't actually test if the system works
my question is: where do I get started, writing-tests-wise, if I want to write "real" tests, that don't mock/stub/fake anything out?
depends what the project does
and how it runs in production
just write tests that call the system as it would be in production without any stubs and see where it crashes because you don't have a service in your test environment
there are also tools for doing that kind of thing, e.g. Cypress seems to be a popular choice
but it's not python
This causes issues... I get this error on startup:
from headers import InstaHeaders as headers
ModuleNotFoundError: No module named 'discord_bot'
.
.
.
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.utilities' raised an error: ModuleNotFoundError: No module named 'discord_bot'```
You need to run it with python -m discord_bot
And you have to do from discord_bot.headers import InstaHeaders as headers
Sorry, had added the above import itself. I had edited the error logs to cover up some names.
Ok well don't do that
python -m discord_bot
How does above work?
It runs your discord_bot.__main__ file and sets up your Python sys.path correctly
Ohh okay, I'll try that and let you know
So it sets CWD to same directory where discord_bot is ?
Or am i misunderstanding smthing ?
it sets sys.path for you so you can do "import discord_bot" or "from . import whatever" and it all works
Oh, alright
you guys have any recommended resources for learning unit testing? And should I ALWAYS unit test my projects, even if it's a small script?
I'm looking for feedback on some tests I wrote, please would someone let me know if they're okay, if they need improvement, etc?
import requests
import unittest
from datetime import datetime
url = "http://127.0.0.1:8000"
def to_iso(datetime_object):
return str(datetime_object).replace(" ", "T")
class CreateUser(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.unique_string = "u6kat2ldn1"
# fmt: off
cls.test_user = {
'user_id': -1, 'first_name': 'TestUser', 'last_name': 'TestSurname', 'email': 'test@step.co.uk',
'biography': cls.unique_string, 'date_of_birth': f"{to_iso(datetime(2000, 1, 1))}",
'creation_date': f"{to_iso(datetime(2021, 1, 1))}",
'pronouns': ["he", "him", "his", "his", "himself"], 'phone_number': '023 9282 0660'.replace(' ', ''),
}
# Make a copy of the dict above
cls.expected_user = dict((key, value) for key, value in cls.test_user.items())
del cls.expected_user["user_id"]
# fmt: on
def setUp(self):
print("Setting up CreateUser")
r = requests.delete(url + f"/delete_user_by_bio/{self.unique_string}")
self.assertEqual(r.status_code, 200)
def test_create_user(self):
print("Testing CreateUser")
request = requests.post(url + "/create_user", json=self.test_user)
self.assertEqual(request.status_code, 200)
self.assertTrue("users" in request.json())
user = request.json()["users"][0]
self.assertTrue("user_id" in user)
del user["user_id"]
self.assertEqual(user, self.expected_user)
def tearDown(self):
print("Tearing down CreateUser")
r = requests.delete(url + f"/delete_user_by_bio/{self.unique_string}")
self.assertEqual(r.status_code, 200)
if __name__ == "__main__":
unittest.main()
Please ping me :)
And uhh, when creating a user, I set the user_id to -1 for API reasons, but want to ignore it because it uses AUTO_INCREMENT in the database, so it's returned id is unknown
If the 8000 port is occupied, the test will break
Hmm, good point! How did I fix that? I probably need to make everything asynchronous
Thanks Darkwind
it's often beneficial to write the tests before the actual code
test driven development
how do you decide what tests to write exactly? thats where im stumped
like how to actually start
the book answers that
and there are book recommendations to continue readings, about TDD included
The book the first point is to explain when and how to write tests
in order for you to give understanding, which tests are helping with minimum maintance effort and maximum result
guess you might find other resources than a 40 euro book
the topic touches software-design a lot
one 40 euro book, teaches materials usually learned for half of a year in online courses/universities and e.t.c.
comparing time and money spent on book with other alternatives... it is shortest and most time efficient way to learn stuff
and since the name is 'unit-testing' it seems that it doesnt cover 'higher' tests
it covers
as a start, whenever you find a bug, write a minimal test example that will fail due to this bug and fix it until the test runs smoothly
hmmm. that logic sounds backwards
but ill do some research and get some clarity
thank you both!
then more forward logic:
When u need to write new functionality/feature, write it first in a test.
Then copy result(import function from same place) to main program ;b
Or even better.
When u write new feature... write test first describing what that feature is without implementing it yet.
Then start thinking how to implement it while keeping in mind how to test it the best/the easiest way
Implement it and have it program and testable in a test to pass the test.
if I've got a couple files I need to test against, where should I store them?
what do you mean by against?
with open("test_collection.db", "r") as test, open("default_collection.db", "r") as default):
self.assertEqual(test.read(), default.read())```
test_collection being the resulting file from running the test
I store files with my tests like
numpee_as_np
├── core
│ ├── foo.py
│ ├── __init__.py
│ └── test
│ ├── example.csv
│ ├── __init__.py
│ └── test_foo.py
├── __init__.py
└── __main__.py
then I do:
import importlib.resources
files = importlib.resources.files(__package__)
def test_foo():
example = (files / "example.csv").read_text(encoding="utf8")
why importlib?
I got that from the code lol, why use that over open?
because open looks in the cwd
and importlib.resources.files(__package__) looks in the package
and works pretty much no matter how your package is installed
eg it could be a zip file or an egg or a whl or whatever
gotcha
also if you're just doing:
with open(...) as f:
v = f.read()
it's better to use .read_text(...)
eg v = (files / "some_file").read_text(encoding="utf8")
ok cool good to know
And if you are reading from a resource, there is even importlib.resources.read_text(__package__, "example.csv")!
Hmm... I remember reading that sub-directories are not supported yet. Wonder if that has changed yet.
That's deprecated
They basically deprecated everything in there when they added the files function
Really? I don't see it in the docs.
Check the 3.11 version
Ah..
Looks like I have some grep-ing to do.
This is going to be a pain to sieve through...
Thanks for the heads-up about the deprecation!
sieve through? there's literally one function you can call now .files(__package__)
ah I see
yeah basically
honestly "open_text" and "read_text" has an ok interface
@dense bough also one to watch out for .files().open_text encoding default to the filesystem encoding and not utf8
That's the case for open() as well.. super scary to think I've basically been omitting it when I should've used it
can you help?
def name(self):
return self.__name
@name.setter
def name(self, value):
if not value.isalpha():
raise ValueError("Team Name can contain only letters!")
self.__name = value```
how do I unit test this?
Show your full code and use ```python
class Team:
def __init__(self, name: str):
self.name = name
self.members: Dict[str, int] = {}
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
if not value.isalpha():
raise ValueError("Team Name can contain only letters!")
self.__name = value
def add_member(self, **name_age):
added_members_by_name = []
for name, age in name_age.items():
if name not in self.members:
self.members[name] = age
added_members_by_name.append(name)
return f"Successfully added: {', '.join(added_members_by_name)}"
def remove_member(self, name: str):
if name in self.members:
del self.members[name]
return f"Member {name} removed"
else:
return f"Member with name {name} does not exist"
def __gt__(self, other): # "other" is another instance of class Team!
if len(self.members) > len(other.members):
return True
return False
def __len__(self):
return len(self.members)
def __add__(self, other): # "other" is another instance of class Team!
new_team_name = f"{self.name}{other.name}"
new_team = Team(new_team_name)
new_team.add_member(**self.members)
new_team.add_member(**other.members)
return new_team
def __str__(self):
result = [f"Team name: {self.name}"]
members = list(sorted(self.members.items(), key=lambda x: (-x[1], x[0])))
result.extend([f"Member: {x[0]} - {x[1]}-years old" for x in members])
return "\n".join(result)
this is the code
i need unit test for this
can you help?
Why didn't you use ```python ?
i used it
def foo() -> None:
pass
That's what happens if you use it
Screenshot the message before you send it?
You need a newline between python and from
from typing import Dict
class Team:
def __init__(self, name: str):
self.name = name
self.members: Dict[str, int] = {}
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
if not value.isalpha():
raise ValueError("Team Name can contain only letters!")
self.__name = value
def add_member(self, **name_age):
added_members_by_name = []
for name, age in name_age.items():
if name not in self.members:
self.members[name] = age
added_members_by_name.append(name)
return f"Successfully added: {', '.join(added_members_by_name)}"
def remove_member(self, name: str):
if name in self.members:
del self.members[name]
return f"Member {name} removed"
else:
return f"Member with name {name} does not exist"
def __gt__(self, other): # "other" is another instance of class Team!
if len(self.members) > len(other.members):
return True
return False
def __len__(self):
return len(self.members)
def __add__(self, other): # "other" is another instance of class Team!
new_team_name = f"{self.name}{other.name}"
new_team = Team(new_team_name)
new_team.add_member(**self.members)
new_team.add_member(**other.members)
return new_team
def __str__(self):
result = [f"Team name: {self.name}"]
members = list(sorted(self.members.items(), key=lambda x: (-x[1], x[0])))
result.extend([f"Member: {x[0]} - {x[1]}-years old" for x in members])
return "\n".join(result)```
Done
Yay
You forgot type annotations on most of your methods?
from project.team import Team
import unittest
class TestStringMethods(unittest.TestCase):
_TESTNAME = "TestName"
_TESTNEWNAME= "alabala"
_TESTDICT = {}
def setUp(self) -> None:
self.test_shop = Team(self._TESTNAME)
def test_init(self):
self.assertEqual(self._TESTNAME,self. test_shop.name)
self.assertDictEqual(self._TESTDICT, self.test_shop.members)
def test_remove_member(self):
result = self.test_shop.remove_member(self._TESTNEWNAME)
expected = f"Member with name {self._TESTNEWNAME} does not exist"
self.assertEqual(result, expected)
if __name__ == '__main__':
unittest.main()
this is my unit test
What tests do you have so far?
so far
Yeah
Currently what tests do you have?
Oh I see your post
Honestly there's no need to bother with a setUp for this sort of system under test
Just make a new Team in the body of any test
Also all of those constants are pointless - the constant is longer than the value
I'd probably write
def test_name_invalid():
t = Team("ham")
with pytest.raises(ValueError, match=r"Team Name can only contain letters!"):
t.name = "2"
assert t.name == "ham"
And another for a valid name
im on pycharm
Use the pycharm "help -> find action" tool
Screenshot?
Did you try Rename all occurrences?
The -m version allows current directory to be searched for test modules.
Usually you don't want to use python -m pytest
Are there any recommended ways to unit test custom pytest fixtures?
Specifically, I want to test the fixture clean-up.
Nevermind. I can probably make it work with pytester.
hey, can we parameterize a fixture list
@pytest.fixture()
def blah():
return [1, 2, 3, 4]
@pytest.mark.parametrize('a', blah)
def test_a(a):
assert a == 1
i know it's possible without fixture
Just name the parameter blah instead of a and that code will work
play_with_test.py:None (play_with_test.py)
Fixture "blah" called directly. Fixtures are not meant to be called directly,
but are created automatically when test functions request them as parameters.
See https://docs.pytest.org/en/stable/fixture.html for more information about fixtures, and
https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly about how to update your code.
@pytest.fixture()
def blah():
return [1, 2, 3, 4]
@pytest.mark.parametrize('blah', blah())
def test_a(blah):
assert blah == 1
i got an error
Remove the parametrize
@pytest.fixture()
def blah():
return [1, 2, 3, 4]
def test_a(blah):
assert blah == 1
Pytest will call the fixture
@frigid basalt , it's work but i want to test each element seperatly
@frigid basalt i have mentioned that i want it as parametrize
Do you need blah to be a fixture? You could just have it be a normal function you call.
i know that too
but in my case i have a dynamic fixture
@frigid basalt i know that too
I am a bit confused, I don't know how to help.
@frigid basalt I'm confused too, I don't know how to solve it
😋
Can I do not pass @mock.patch('...', return_value=...) mock as an argument to an invoked function?
Why? I don't need it. Moreover - among other 10 mocks it is hard to maintain the correct order.
Is _ the only option?
Use the context manager interface
You can put all 10 patch calls in the same with statement
But that's a lot of patches, maybe write your tests without patch instead?
Isn't it much readable.
Yea, I of course know that's so many patched, but it's unavoidable
It's much readable yes
Ooo, with some mocks (that we care about) as @ and the others in with statement - yeaa, better
The context manager lets you directly associate the patch and the value without having to count up args backwards
using hypothesis:
import hypothesis.strategies as strats
@given(strats.text(), strats.integers())
def test_base_charset(text, integers):
"""The characters in the base charspace must come from the charset
properties."""
sp = Charspace(
blocklist=text,
extras=text,
uppers=text,
lowers=text,
digits=str(integers),
)
everything = sp.extras + sp.uppers + sp.lowers # + sp.digits
assert all(char in everything for char in sp.base_charset)
Is my use of strategies.text() giving me different text for different properties, or is it going to be the same on each pass? I assume the latter. Do I need to do strats.text(), strats.text(), strats.text(), strats.text(), like this or is there a better way?
You use property not right, you dont need name mangling here. Use it like this. Its common pattern, when u create private attribute in constructor, and open calculated public property.
' py
class Team:
def init(self, name: str):
self._name = name
self.members: Dict[str, int] = {}
@property
def name(self):
return self._name
'
:incoming_envelope: :ok_hand: applied mute to @calm oak until <t:1639643438:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
my question is how to do a unit test on this
i don't want you to fix the code
Can anyone help me out with an issue I'm having with unit tests, mocking/patching and assert_called_with: https://stackoverflow.com/questions/70381238/pytest-mocker-patch-is-returning-noncallabalemagicmock
anyone know how to mock.path("path.to.some_async_fn", side_effect=some_other_async_fn) ?
I sort of expected it to await the some_other_async_fn
!e
import pytest
from unittest import mock
class Foo:
async def bar(self):
pass
@pytest.mark.anyio
async def test_foo():
async def fake_bar():
return 0
with mock.patch.object(Foo, "bar", side_effect=fake_bar):
assert await Foo().bar() == 1
pytest.main()
@hexed cloak :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 15, in <module>
003 | File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
004 | return loop.run_until_complete(main)
005 | File "/usr/local/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
006 | return future.result()
007 | File "<string>", line 13, in test_foo
008 | AssertionError
!e
import pytest
from unittest import mock
class Foo:
async def bar(self):
pass
@pytest.mark.anyio
async def test_foo():
async def fake_bar():
return 0
with mock.patch.object(Foo, "bar", side_effect=fake_bar):
assert await Foo().bar() == 1
pytest.main()
ah dang
!e ```python
import pytest
from unittest import mock
class Foo:
async def bar(self):
pass
@pytest.mark.anyio
async def test_foo():
async def fake_bar():
return 1 # This was set to 0?
with mock.patch.object(Foo, "bar", side_effect=fake_bar):
assert await Foo().bar() == 1
pytest.main()
@frigid basalt :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | ModuleNotFoundError: No module named 'pytest'
Oh?
How come this got far enough
Oh I edited it xD
But too late for the rerurn
Oh lol
Oh lol I got the wrong number in there
But when I run it locally I get a Coroutine back from await Foo().bar()
!e
import anyio
from unittest import mock
class Foo:
async def bar(self):
pass
async def test_foo():
async def fake_bar():
return 1
with mock.patch.object(Foo, "bar", side_effect=fake_bar):
assert await Foo().bar() == 1
anyio.run(test_foo)
@hexed cloak :warning: Your eval job has completed with return code 0.
[No output]
That would make sense
Yeah I saw that was like..
smh
Not sure if this belong in here, but here we go. I'm trying to use cibuildwheels to build wheels, and there are some tests that I can get to run but fail because the files it relies on lives in a different directory. Anyone come up with the "best" way of handling this?
Which file(s) does the test rely on? Why are they in a different directory than expected? How is it related to cibuildwheels? Are you using this https://cibuildwheel.readthedocs.io/en/stable/options/#test-command ?
Yeah, it's a cibuildwheels thing. There's files in /examples/samples/ that are part of the test suite. cibuildwheels uses a new venv to test wheels in and doesn't use/have access to the project folder. For linux I managed to get it to copy them across by using this;
CIBW_BEFORE_TEST_LINUX: mkdir -p ~/examples/samples && cp -R {project}/examples/samples/* ~/examples/samples/ however I stalled out with windows :/
How about making your tests read the path from an environment variable. Then you can just set the environment variable to a path relative to {project} and cibuildwheel should be able to replace that with the actual path, right?
You could also give it a default value for when you want to run tests locally.
os.getenv(TEST_DATA_PATH, "examples/samples")
Hmm that's a great idea
Any suggestions on the best way to test data pipelines accurately?
what kinds of data pipelines?
if the pipeline is "plain" python code, then you can test the python code as usual
testing "data processing" code can be difficult, because it can be difficult to come up with invariant properties to test
for ETL systems e.g. using airflow, i'm not sure what the industry standard is... but at minimum you can run some sample data through the full pipeline and make sure it doesn't return any errors, the number of rows is correct, the column names are all correct, check for data types, etc.
it seems like silly obvious stuff, but you never know when you introduce a typo that breaks something
I have some code that needs to be tested in specific environments. I'm not used to testing at this "higher level". How would I provision these environments for automated tests? For example, I need environments with certain cgroup version, swap memory on and off, and the swap memory cgroup controller on and off.
Furthermore, let's say I somehow already had all these environments ready to go. How should I approach writing the actual tests? The expected behaviour I need to assert will differ depending on the environment. Should I write a separate test for each environment that only runs if in that environment?
smh i wondered what this was related to at first read lol
maybe you need to set up a bunch of virtual machine images. and you can set a special environment variable or create a specific file that indicates the current test environment
e.g. MYAPP_TEST_ENV=foo123 or echo foo123 > /etc/myapp/test-env
Yeah I was thinking something along those lines.
Does anyone have practical experience with this? Anyone have tests that rely on specific environments that can't feasibly be mocked? Would love to hear how others have set it up.
I suppose a popular form of this is OS-specific code. CI mostly supports this use case out of the box though. Setting up runners with specific Linux kernel parameters... not so much.
Hi, how does one go about testing your application's HTTP requests? Referring to actually testing the whole stack, including the network call, and I'm comparing with Java where there is WireMock, a HTTP server that you set up during testing to respond to your http requests locally
I'm yet to find a similar library for python, they all seem to 'mock' the http request and don't actually make the API call. is this the norm with python?
This is more end-to-end / integration testing territory but I didn't find a more appropriate channel
Only httpretty seems to be close to that but I'm not sure it does what I need to either
Or if I should even be bothering at this level and should just care that the endpoint is called without my application actually doing the http request at runtime
The other one is responses
Do you mean something like https://pytest-httpserver.readthedocs.io/en/latest/tutorial.html#tutorial
exactly what I was looking for. However, I have 2 problems
- I'm using unittest instead of pytest, is it a good practise to use both unittest and pytest as I can't immediately find a unittest alternative?
- I'm using an api wrapper library which talks to real apis ( test environment & live ) and i might not be able to set the base url to localhost
but this is what I was looking for regardless, thank you
which is basically talked about in the docs you sent:
Some code changes required in the original source code. The code should accept the server endpoint (host and port) as a parameter or by some means of configuration. This endpoint will be set to localhost during the test running. If it is not possible, you need to tweak name resolution.
I'll see if i can make that happen although it's not possibly out of the box in the library im using
- No issue with that, you might have to make some changes to get it to work (not sure if there's an example on the wiki)
- That's mentioned in the how-to https://pytest-httpserver.readthedocs.io/en/latest/howto.html#customizing-host-and-port
Thank you so much!
I guess I need to improve my googling skills, should have been able to find this
Can anyone help me with mocking a class with property and setters than access a "private" attribute: I've outlined the problem here: https://stackoverflow.com/questions/70464598/pytest-mocking-property-and-setter
Hi, similar to my question above, I'm now looking on testing my WebSocket client. It simply connects to a WS server and subscribes to a topic. I want to write a test for this that would ideally start a fake ws server and send a message to the topic that my app would consume
Is there a python library that achieves somethings along these lines? Ideally not mocking but actually making use of the network TCP layer
Trying aiohttp's websocket & test support, hope it might do it. If anyone has feedback please provide it 🙂
https://github.com/aio-libs/aiohttp/blob/master/tests/test_web_websocket_functional.py
:incoming_envelope: :ok_hand: applied mute to @regal folio until <t:1640431334:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
Hello, is it possible to unit testing web scraper project? Do I need to mock the html response first?
For unit testing a web scraper your best bet will probably be to download a webpage locally and open it with BeautifulSoup (see https://stackoverflow.com/a/21577649)
You can test all parts of your code with that - mocking http responses will depend on which request library you are using (e.g. for httpx there is https://pypi.org/project/pytest-httpx/)
Hi, thanks for the answer.
Right now I'm using Bottle micro framework, I'm still confused how to do the unit test without rewriting the scraping algorithm, do I need to create another separate function and calls it inside bottle default function so that I can use it later in test?
Thanks again.
I'm already see the unit-testing approach in Bottle documentation: https://bottlepy.org/docs/dev/recipes.html#:~:text=them in production.-,UNIT-TESTING BOTTLE APPLICATIONS,-¶, but the problem is the test will be flaky because this test doesn't mock the response of the scraping request.
Hard to say without being able to see your code, but in general to test code you have to design it to be testable. That might mean you need to shift things around
Solved using responses library to mock requests, thanks.
Hi everyone
Hey @spiral geyser!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
I'm having trouble testing this function. I want to test that the arguments given via CLI are actually used. Is this just a case where I need to mock the function and assert the args its called with? I've been trying to avoid that.
def main():
args = parse_args()
result = NsJail().python3(args.code, nsjail_args=args.nsjail_args, py_args=args.py_args)
print(result.stdout)
if result.returncode != 0:
sys.exit(result.returncode)
you could mock NsJail, sys.exit instead, I suppose
How is that different than what I said
so this function can be invoked via CLI?
they don't mock anything, call it in your test externally via os.system or smth like that
and check its response in stdout 😉 (better to use subprocess.run with capturing stdout I guess then)
lets make it as much black box testing as possible
mocks should be avoided when it is possible, since they make tests fragile
The problem is that I can't find a good way of ensuring the arguments are passed in a black box way
Testing their behaviour is not straight forward
Nsjail args are passed to a subprocess, which in turn spawns a Python subprocess which uses the py args.
so you want to make an integration test with nsjail?
I guess you could test individual things, like --binding a temporary folder to a known location and then reading form that known location in the Python code.
you'll have to test the "real thing" eventually, right? you can't mock forever
I do test the real thing, but through the python3 directly rather than the CLI entrypoint (which is mainly there for debugging/development purposes)
@fiery arrow
So it doesn't necessarily have to be an integration test, but it would be nice to not tightly couple tests to code with mocks.
I can test the return code easily. I can test that it prints stdout easily. The arguments are just the problem, particularly the Python arguments. For NsJail args at least I can set a time limit and execute code that sleeps longer than the limit.
wdym python args?
You can just use sys.argv in the Python code, can't you?
or maybe I'm misunderstanding
It's interpreter args
oh, it's the arguments to python itself
well, python 3.10 has an attr containing them and there's another flag for that too in earlier versions
@kind meadow try -O and check that an assert False doesn't work
!d sys.flags
sys.flags```
The [named tuple](https://docs.python.org/3/glossary.html#term-named-tuple) *flags* exposes the status of command line flags. The attributes are read only...
or that lol yes, TIL
And ideally, I could create a test case that passes both nsjail and py args, otherwise my test won't tell me if they work together (even though I do have unit tests for parse_args already)
!d sys.orig_argv
sys.orig_argv```
The list of the original command line arguments passed to the Python executable.
See also [`sys.argv`](https://docs.python.org/3/library/sys.html#sys.argv "sys.argv").
New in version 3.10.
Thanks, that might work
I've never read through all of sys's docs on a whim 🤡
Hey, I need to start testing this application https://github.com/HicaroD/tChat
To be very honest, I don't really the mindset of a tester, I just don't know how to start. I was trying to figure out where my application could break and the only thing that comes in my mind is network problems, in case of the internet doesn't work, the program just crash.
So, any tips about how to test it or even tips about testing in general
Talking about pytest, if I have two fixtures in a test function:
- What is the evaluation order? Is it left to right?
- What if both of them have a yield? Will both of the fixture stop until test is run to teardown?
1: that's indeterminate with just that info, as fixtures can depend on each other.
2: yes
trying to do unit tests in django keeps returning "0 tests found"
What is your testing framework
https://docs.djangoproject.com/en/4.0/topics/testing/overview/
I think it's a good start
It teaches you how to write and run tests in Django
hey guyzz
is it fine?
i have actually created a weight converter..
weight = int(input('Weight: '))
unit = input('(L)bs or (K)g: ')
if unit.upper() == "L":
converted = weight * 0.45
print(f'You are {converted} kilos')
else:
converted = weight / 0.45
print(f'You are {converted} pounds')
using pycharm
Hello ! I'm wondering if there is any Selenium user here.. I'm following a tutorial on the net which uses the method "find_element_by_xpath" but PyCharm is angry bcs the method seems deprecated.. What would be the elegant way to find a button using his text without find_element_by_xpath ?
When starting the function
def run(driver_path):
driver = webdriver.Chrome(executable_path=driver_path)
driver.get('https://tproger.ru/quiz/real-programmer/')
button = driver.
Thanks a lot ! 🙂
Selenium/Python/pytest users could benefit a lot from https://github.com/seleniumbase/SeleniumBase , which is a framework for simplifying Selenium with Python.
from selenium.webdriver.common.by import By
find_element(By.XPATH, '//xpath')```
Does anyone know of a way to test an application that connects to a WebSocket server? Namely, being able to send messages from the WebSocket server running during testing to the application under test, not just the WS server replying to messages sent by the application.
Is this for a Discord API library?
Hi, no. It's for a cryptocurrency project, listening for coin price data
Someone know why send_keys is not sending the whole key sometimes ? I did not have this issue while using Chrome, know when I'm sending some keys, a lot of the text inside is not sent. It also looks like for some unknown reasons Selenium is doing a Ctrl + F and writing my text inside it lol..
wdym?
@open galleon yes.
How do you guys deal with optional tests?
I have some tests in another package that I want to import over - but this package is optional - but I am not sure how to handle it missing. Reporting one warning for say 10 missing tests doesn't seem like reflects what's missing in a sense?
@frigid basalt can you use unittest.skipIf?
try:
import optional_dep
except ImportError:
_optional_dep_available = False
else:
_optional_dep_available = True
@unittest.skipUnless(_optional_dep_available, 'Skipping because optional_dep is unavailable.')
class TestOptionalDepStuff(unittest.TestCase):
...
Oh I didn't realize that "skip" was what I was looking for, awesome!
Is TDD something that someone fairly inexperienced should try and incorporate? Totally willing to, but it will definitely slow me down (for better or worse. Might actually be for better since I can think about what I want to write before writing it)
it might be worth trying it a few times. it might help clarify your thinking and designs. personally i don't do it, because i find that i don't usually have the APIs fleshed out until after i've already started writing the code, and if i write the tests too early in the process i end up having to change them later anyway
but if you write some small utility functions and you know what the interfaces will be, then sure, go ahead and write the tests first
but it's worth at least trying it. some people really enjoy programming that way
one argument in favor of TDD is that you would spend that time debugging anyway
true
test suites can become their own software projects, depending on what you are building
. @frigid basalt definitely was doing this today
😔
Sure. Actually TDD can help the most to unexperienced people.
Because it FORCES you to think architecture of your code in a clean and testable way 😉
Actually I don't even always follow TDD, but I still keep following the main point of it, thinking in how i am going to test my code first before writing it
testable and clean are not necessarily the same thing tho - a very interesting example of this is the stark test philosophy and refactoring philosophy differences of mercurial and bzr
testable enforses minimal clean code quality nevertherless, I agree that not fully and not equal to clean, but still quite considerable leap forward
At least for me quality of tested code is raised at least several times always (even 10 times feels right)
using tests as driver tends to be a big help, but the choosen detail levle is a thing of its own
what's the difference in these philosophies? i have never used either, although i am familiar with comparisons between git and hg
i know approximately nothing about bzr
mercurial is tested using integration tests, the outer facade being the cli with ruthless refactorings of the internals, bzr is tested using quite a number of unittests, it has massive amounts of internal interfaces
a key part however is - if you do mercurial style testing, not doing ruthless refactoring will lead to massive spagetty
the linux kernel also famously follows the former, right? although it also famously doesn't have tests...
the linux kernel is rather strange with the testing strategy, i cant comment too much on that
im just using linux cause its the least painful to me, not cause i think its a good os ^^
i once naively tried to make a "good" os, it was a good lesson in learning not to overestimate oneself
heh
i use linux because of the operating systems built on top of it, not because i have any particular affinity for any particular kernel
i am not enough of a power user to care significantly about the differences between the bsd kernel and the linux kernel... i just know how to use linux-based systems and most software runs on them. good enough for me
its hard to be fond of anything thats build on top of the posix permission/file model ^^
i don't have a reference point for anything better 🙂
but we are getting slightly OT ^^
in beos there was a little attempt ^^ but basically file systems are a pain that jsut store blobs with minimal metadata (which is why so many file formats are also metadata containers ^^)
ahh yeah
i am aware that beos did some fun stuff like that
and that before unix you had pretty complicated filesystems, and switching to 'blobs of bytes' was apparently a big improvement at the time
thats for sure, problem is that schemas and schema validation + evolution is very expensive ^^
Suggestions for the best way to mock a couple levels down into an object?
cs = self.cnx.cursor()
result = []
try:
blah = cs.execute(query)
result = list(blah)
finally:
cs.close()
I want to test this method, meaning I need to have the two methods it calls (cnx.cursor() and .execute() on the object returned by cursor()) mocked, right? What's the best way to do that?
i think i'd probably do something like this
obj = TheClassWithTheMethodYouWantToTest()
with patch.object(obj, 'cnx') as mock_cnx:
mock_cursor = MagicMock(return_value=[ ... ])
mock_cnx.cursor = MagicMock(return_value=mock_cursor)
obj.execute_query()
mock_cursor.execute.assert_called_once_with(query)
mock_cursor.close.assert_called_once_with()
What I've currently got is
expected_result = ['1','2','3']
execute_mock = Mock()
execute_mock.return_value = expected_result
cursor_mock = Mock()
cursor_mock.execute = execute_mock
cursor_mock.close = Mock()
connection_mock = Mock()
connection_mock.cursor = cursor_mock
snowflake_connector_mock.return_value = connection_mock
client = SnowflakeClient(self.settings)
result = client.execute_query('SELECT * FROM DATA')
self.assertEqual(result, expected_result)
But that seems to return a mock object from the execute() method rather than my expected_result list
where the [ ... ] is some fake result data
ah, the classic
you have to patch where it's used
obj = TheClassWithTheMethodYouWantToTest()
with patch.object(obj, 'cnx') as mock_cnx:
mock_cursor = MagicMock()
if query_should_fail:
mock_cursor.execute = MagicMock(side_effect=QueryFailureException())
else:
mock_cursor.execute = MagicMock(return_value=fake_data)
mock_cnx.cursor = MagicMock(return_value=mock_cursor)
obj.execute_query()
mock_cursor.execute.assert_called_once_with(query)
mock_cursor.close.assert_called_once_with()
Ohhh you mean where it's consumed in the actual class I'm testing
I have read about that but still don't have it understood well enough
yes
but in this case it sounds like you want to patch one specific object anyway instead of the whole class
Yea I need to mock methods on an instance
but also this seems like you're patching deep into SnowflakeClient which is 3rd party code
and you usually don't want to patch into 3rd party code if you can avoid it
Yeah...honestly I'm only writing these tests because SonarCloud requires 80% coverage. IMO this doesn't even really need a test! But I have to add something. So I figured I can mock the Snowflake connection stuff, have it return some specific data, then just verify that my function invokes the snowflake connection to get that data
yeah it's not bad to test "small" methods imo
but just be careful about what you're mocking, whether it depends on internals of other packages or not
I think my larger issue is not understanding why it doesn't get the return value back in this instance
@rare hill where does snowflake.connector.connect actually get used?
did you write SnowflakeClient or is that 3rd party code?
i assume that's the class you are testing?
you need to do the patch in the module where SnowflakeClient is defined
I am in pretty big pain and looking for how to parametrize my tests or somehow reduce code. I have a suite of ratelimiting tests. I want to test a bunch of combinations of:
- Same/different ratelimit bucket (a key in a dictionary)
- Same/different endpoint (an instance of a class)
- Same/different major parameter (value into the instantiation of the former class)
I also want to make some tests without the bucket, because that may be missing.
A typical test looks like this: https://paste.pythondiscord.com/ofenumujor.sql
I've been thinking about what/how I can parametrize but I am not sure if anyone has any ideas on how to structure my tests?
I want to test essentially all possible combinations of same/different XYZ. Which becomes:
# 12 tests:
# - S stands for Same, D for different
# Bucket, Endpoint, Major parameter
# SB, SE, SM
# DB, SE, SM - SB, DE, SM - SB, SE, DM # 1 different (3 tests separated by the '-')
# DB, DE, SM - SB, DE, DM - DB, SE, DM # 2 different
# DB, DE, DM
# SE, SM
# DE, SM - SE, DM # 1 different
# DE, DM
The sample test I showed tests SB, DE, SM
Should I just look to replace the changing parts with variables or any ideas of how I can test it differently?
ngl, every time I see "Permission denied" I'm afraid I destoy some bearing wall with my head
worst error of all time
If I am testing a class method and I need to iterate through many different instances (with different attributes) and iterate over many method parameters, what is the easiest most pythonic way to do that?
...or resources for doing that? Most unit testing resources seem focused on testing parameters.
if you are using unittest, it sounds like you can just write a loop and use subTest. if you are using pytest, it sounds like you want parametrize
Update on this, I have somewhat succeeded! Now, I realize that there's even more combinations I want to test (I want very thorough coverage and considering I know there's a finite number of combinations I would really like to write good tests that test this)..
For example, different major parameter value but also different major parameter at all (only possible with different endpoints, maybe not worth it then?) would be another set of combinations I haven't thought about. Am I testing too much and being over the top or is there maybe any idea how I can generate these combinations during runtime when the tests are loaded so it doesn't look so messy?
Here's how it looks right now, this tests the latter comments that doesn't consider buckets: https://paste.pythondiscord.com/qisuzepayi.py
What are some nice ways to deal with long test data for pytest's parametrize decorator? I don't find multi-line decorators to be particularly readable. Should the data be put in another Python file and then imported? What other options have you seen that you've liked or done yourself?
Moving to another file sounds about right.
As long as tests and file dependencies lie outside of folder with main code
Tests should not be in the way of main code
Or as an option, you could try moving this big test in a separated file 😉
I have two approaches to keep tests
- Django way, when tests.py file at the same place where the package of the code
- test files in separate folder outside of the main code
in second option i try to name then precisely with sub categories like
tests_category_thing.py
makes them organized more or less
but I guess all those file organizations depend on amount of present code/tests
TLDR: moving just data to external file sounds right, because it is usually comfortable to have tests of the same category easily scrolled together 🤔
It should be more comfortable than having big test in a separate file
pretty sure he wasn't asking about whether tests should be in a separate file, but rather whether the data for the parametrized decorator from pytest library should be in one @maiden pawn
i voiced alternatives to it and compared with first suggested approach
Thanks
Hi, i'm new to unit testing and I wanted to test my Quart app with pytest, but can't figure out how to do so. Tried following some documentations but got nowhere. Basically at first I tried making a directory containing all my test files and tying out a simple test on a function written in the service directory.
|---->App------|
|------->routes
|------->services------>file which contains the function to be tested
|------->tests------->file containing test cases
but when I tried to run tests using pytest I faced some import errors, then I got a solution which looked kind of hacky but worked out, basically by adding init.py in every directory the import issue was fixed. But them came along another challenge, adding support for globals.
Using pytest with quart is kind of confusing and I'm stuck. Don't know how to write tests for things in such a complex service, where there is a heavy use of globals, db queries and complex logics.
Any suggestions would mean a ton 🤞
reading carefully
https://realpython.com/absolute-vs-relative-python-imports/
and doing something like...
going explicitely to folder from which you are launching your app
and launching test from the same folder
and writing imports in your tests in absolute starting from that folder or in relative way
considering your case, relative imports should work fine too 🤔
import will look like...
from ..services.file1 import abc
def test1():
assert abc==123
abc=123
__init__.py files are just empty files
runs fine
(venv) naa@naa-MS-7C89:~/repos/experiments$ pytest
=============================================================================== test session starts ===============================================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/naa/repos/experiments, configfile: pytest.ini
collected 1 item
app/tests/tests.py .
i provided relative way
check carefully where i was launching the tests
naa@naa-MS-7C89:~/repos/experiments$ pytest
it is a parent folder to app folder
How would I write a marker/fixture to run a test twice?
For example, let's pretend I want to test my comparison operator implementation:
@pytest.mark.parametrize(
['a', 'b', 'returns'],
[
(1, 2, False)
]
)
def test_compare(a, b, returns):
assert (a == b) is returns
I want to run the test both with test_compare(1, 2, False) and test_compare(2, 1, False). Any tips?
import pytest
@pytest.mark.parametrize(
"a, b, returns",
[(1, 2, False), (2, 1, False)],
)
def test1(a, b, returns):
assert (a == b) is returns
I believe you just have to duplicate the tuple and flip the values
How come I can use @pytest.mark.anyio and it will run my test twice (albeit with different event loops)?
There seems to be some mechanism to run a test multiple times
Do you want to make your own decorator to do that? Is that what you're getting at?
I have a substantial amount of parametrize cases, I would prefer to not repeat it.
Yes, that's what I was looking to do.
I don't know where to start with it though, because most fixtures just provide some value that's used - they don't run the test multiple times like parametrize
I'm not sure how to execute the test multiple times
If anyio does it you can look at its source, or look at parametrize's source
Looks like it's related to Metafunc.parametrize
After looking at it for a while I found this: https://github.com/agronholm/anyio/blob/master/src/anyio/pytest_plugin.py
I guess you can just decorate it multiple times with parametrize
and make a wrapper decorator to hide that stuff
But it's unclear to me where it's called multiple times
So a parametrize that takes input from the the other parametrize?
The docs use this as an example
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
pass
This will run the test with the arguments set to x=0/y=2, x=1/y=2, x=0/y=3, and x=1/y=3 exhausting parameters in the order of the decorators.
It also talks about the metafunc here actually https://docs.pytest.org/en/stable/parametrize.html#basic-pytest-generate-tests-example
Ah, right. If I do this then it'll try each combination with the pre-determined result as well I think, but that's a step in the right way yeah
pytest_generate_tests looks quite useful for this situation, I'll look into it more thanks.
np
Hey guys, never used unit testing before but can see the advantage in it, do you have any recommended resources to get into it with quickly?
Thanks a lot 😃
Where does tox look for python versions? For example i have this error: ERROR: InterpreterNotFound: python3.8, but I know for certain that I have python 3.8 on this computer installed via pyenv.
On $PATH I have /Users/me/.pyenv/shims - is there something else which is required?
I'm trying to follow a basic tutorial - which is here: https://github.com/ChristopherGS/tox_examples/tree/master/multipython , and from within the multipython directory I have run python -m venv venv && source ./venv/bin/activate, which has created and sourced a venv using Python 3.9.5 . I've changed the line here https://github.com/ChristopherGS/tox_examples/blob/master/multipython/tox.ini#L2 to this: envlist = py37,py27,py38,py39
ping me if you respond please
If pyenv is involved, you may need the tox pyenv plugin to get its pythons as they are a bit out of sight
hm ok thanks - any appropriate documentation you're aware of for this?
not off-hand, not using pyenv myself
i use python virtual environments as well "venv". the command you ran python -m venv venv && source ./venv/bin/activate creates the virtual environment 'venv' on your system in the CD (Current Directory), the second half runs a bat command script that will cause your terminal to take python commands such as pip install, the python interpreter, and run python scripts from that directory. The reason to use them is because it keeps a contained list of installed modules from PIP so you don't have leakage or versioning problems with other software you maintain or write. It has an optional argument that can be helpful for modules you use on everything (pandas anyone?) called --system-site-packages that will allow the virtual environment to use the system based packages (those installed outside any venv) and use them
OH!! the interpreter not found error, do you have python installed in the system path variable? if not, look up how to add Python to PATH for your system
@carmine plume i'm aware of virtual environments - i'm not familiar with tox
I have pyenv on the path as the shims path
i mean Python3.8 itself. Is it located on the system path EV? If not, it doesn't know where to look when you do python
I don't explicitly have any python version on the path - i probably have 3.9 installed somewhere 3.8 isn't though
@carmine plume are you familiar with tox ?
That is where your problem lay then. Never heard of tox
@carmine plume this is tox specific - everything else you've mentioned i'm aware of
so what does your tox.ini look like? the envlist you posted what about any other modifiers?
I've linked that already
im blind
its going to be hard then i guess - here #unit-testing message
I think tox automatically makes makes the venv and it just checks for the PATH location of python3.X command (at least on linux), so if running which python3.9 gave you /usr/bin/python3.9, that's the version it used.
or well that's the version it used to make the venv
yeah when i run which python3.8 i get the path to the pyenv shim
and does tox not use that?
If you need to set an environment variable like PYTHONPATH you can use the setenv directive:
[testenv]
setenv = PYTHONPATH = {toxinidir}/subdir
usually if i wanted to use a different version id set it with pyenv 🤔 like local or global etc
maybe?
not automatically it doesn't seem
perhaps this is needed: https://pypi.org/project/tox-pyenv/
yeah, you need a similar pkg installed when working with poetry
I don't know much about pyenv though
i use pyenv and poetry usually, only just looked at tox today though
with poetry, you just need tox-poetry
poetry is for project deps though, not python versions
yeah but tox needs to install those versions listed in poetry in it's venvs
hrm ok maybe i should look at that too
Environment variables (from: https://tox.wiki/en/latest/config.html?highlight=environment#advanced-settings)
tox will treat the following environment variables:
TOX_DISCOVER for python discovery first try the python executables under these paths
TOXENV see envlist.
TOX_LIMITED_SHEBANG see Handle interpreter directives with long lengths.
TOX_PARALLEL_NO_SPINNER see Parallel mode.
_TOX_PARALLEL_ENV lets tox know that it is invoked in the parallel mode.
TOX_PROVISION is only intended to be used internally.
TOX_REPORTER_TIMESTAMP enables showing for each output line its delta since the tox startup when set to 1.
TOX_SKIP_ENV see envlist.
TOX_TESTENV_PASSENV see passenv.
TOX_DISCOVER i think will help find python
i don't think i ever explicitly list versions in the pyproject.toml, it's just like >=3.8 or something, from that will it infer 3.8, 3.9, 3.10 - or are we referring to something else with "versions listed in poetry"
that's fine, the versions should be defined in tox
but the dependencies are picked up from pyproject
i.e. say your project needed to have aiohttp installed
yeah that makes sense - i have package/dev deps in the toml and lock file
yeah, tox-poetry lets tox pick up on those dependencies
you don't use pyenv - so you just have multiple versions on PATH or something?
yeah, I just built them from source and keep them in /usr/local/bin
(which is in my PATH)
if you're on arch-based linux distribution, you can also use AUR though, it'll build the versions for you
i'm just on mac os
then you can just build it yourself, or ig there are the binaries for it too somewhere on the python website
Cool, I just thought pyenv was the recommended approach to managing python versions, I'll have a look at these plug ins though
it's probably possible to use it, I just don't have experience there
this may help? https://yellowdesert.consulting/2020/10/24/tox-testing-multiple-python-versions-with-pyenv/
oh thanks ill have a look
First time writing tests with factory-boy, pytest-django, Faker and django-test-plus packages. Any kind of constructive criticism is welcome:
https://github.com/Ksenofanex/stock-management-api/tree/master/api/tests
I would recommend using pytest.
At the moment u a essentially using unittest, but since pytest is backward compatible with unittest, it is possible to run unittest tests in pytest
I'm already using pytest.
I couldn't do this without pytest, right?
https://github.com/Ksenofanex/stock-management-api/blob/master/api/tests/test_models.py#L37
api/tests/test_models.py line 37
assert self.material.name == "Tesla Model 3"```
Can't be seen in the code
This is just default inbuilt python, no library method ;)
Not really.
https://docs.pytest.org/en/6.2.x/assert.html#assert
https://www.mattlayman.com/understand-django/test-your-apps/
My biggest reason for using pytest-django is that it let’s me use the assert keyword in all of my tests. In the Python standard library’s unittest module and, by extension, Django’s built-in test tools which subclasses unitttest classes, checking values requires methods like assertEqual and assertTrue. As we’ll see, using the assert keyword exclusively is a very natural way to write tests.
How do you confirm that your website works? You could click around and check things out yourself, or you can write code to verify the site. I'll show you why you should prefer the latter. In this Understand Django article, we'll study automated tests to verify the correctness of your site.
!eval
assert 1 == 1
print ("finished testing")
@maiden pawn :white_check_mark: Your eval job has completed with return code 0.
finished testing
No library method ;)
Have you read the sources I've sent? I'm not talking about the built-in assert keywords. AFAIK using assert keywords with Django's testing cases is not possible.
You are missing the point.
Yes, u can't use it with unittest but still
U a using just a single feature of pytest out of all
I would not even count it as pytesting
Pytest usage
Yeah, I got that. Examples/sources?
Sure, in few minutes
import pytest
def test_simpliest_test():
assert 1 == 1
@pytest.mark.parametrize("x", [1,2,3,4,5,6,7,8,9])
def test_that_runs_9_times_with_different_data(x):
assert x < 10
@pytest.mark.parametrize("x,y", [(2, 4), (3, 9), (4, 16)])
def test_parametrized_to_run_three_times_with_different_multiple_data(x, y):
assert x * x == y
@pytest.fixture()
def reusable_var1():
return "reusable data across multiple tests, can be stored in special file conf something to be reusable across pytest files"
@pytest.fixture()
def reusable_var2():
return "reusable data across multiple tests, can be stored in special file conf something to be reusable across pytest files"
def test_with_application_of_reusable_data(reusable_var1, reusable_var2):
assert reusable_var1 == reusable_var2
def test_reusable_data_fixtures_initialized_only_which_you_write_as_function_variables_for_the_test(reusable_var1):
"note: for every test, if I remember correctly fixture is running from zero again in order to be not influencing other tests with changable data"
assert reusable_var1 == "reusable data across multiple tests, can be stored in special file conf something to be reusable across pytest files"
@pytest.fixture()
def setup_and_teardown_data():
print("setup")
yield 123
print("breakdown")
def test_that_utilizes_data_which_is_initialized_before_test_and_destroyed_after_the_each_test(setup_and_teardown_data):
print("123")
assert setup_and_teardown_data == 123
pytest makes tests as simple as possible with moving its special functionality into python decorators
one of the convinient pytest features, that you can easily run particular test with just writing even partial test name
pytest -s -k test_that_utilizes_data_which_is_initialized_and_destroyed_after_the_each_test
test name is enough to run it, or part of the name
-s makes outputed console data during the test running
Thanks, but I'm already using -s and -k flags during local testing. I'm just not using fixtures of pytest since I'm using factory-boy package for that.
u a welcome. as a funny another convinience pytest fixtures / reusable data are reusable across themselves too 😉 they can be chained
@pytest.fixture()
def first_data():
return 1
@pytest.fixture()
def second_mutated_data(first_data):
return first_data+2
@pytest.fixture()
def third_mutated_data(first_data):
return first_data+2
def test_chained_data(second_mutated_data):
assert second_mutated_data == 3
def test_chained_data(third_mutated_data):
assert third_mutated_data == 3
plus pytest has module to run all of its tests in multithreading /parallel mode
Thanks but these features aren't really necessary in my case. Good to know though.
pytest-xdist uses multiple processes, pytest itself is not threadsafe as of now
are there issues running pytest in VSCode (on windows)? It runs fine when invoked in Powershell but the testing window reports an error
Which one?
[ERROR 2022-0-11 16:33:12.388]: Error discovering pytest tests:
[r [Error]: ============================= test session starts =============================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: c:\Users\Zach\Desktop\zach_stuff\projects\ACNH_pixel_color, configfile: pytest.ini
collected 0 items / 1 error
=================================== ERRORS ====================================
____________ ERROR collecting tests/test_ACNH_pixel_color_test.py _____________
ImportError while importing test module 'c:\Users\Zach\Desktop\zach_stuff\projects\ACNH_pixel_color\tests\test_ACNH_pixel_color_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
..\..\..\..\AppData\Local\Programs\Python\Python310\lib\importlib\__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests\test_ACNH_pixel_color_test.py:2: in <module>
from ACNH_pixel_color import ACNH_pixel_color
E ModuleNotFoundError: No module named 'ACNH_pixel_color'
=========================== short test summary info ===========================
ERROR tests/test_ACNH_pixel_color_test.py
!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
==================== no tests collected, 1 error in 0.33s =====================
Traceback (most recent call last):
File "c:\Users\Zach\.vscode\extensions\ms-python.python-2021.12.1559732655\pythonFiles\testing_tools\run_adapter.py", line 22, in <module>
main(tool, cmd, subargs, toolargs)
File "c:\Users\Zach\.vscode\extensions\ms-python.python-2021.12.1559732655\pythonFiles\testing_tools\adapter\__main__.py", line 100, in main
parents, result = run(toolargs, **subargs)
File "c:\Users\Zach\.vscode\extensions\ms-python.python-2021.12.1559732655\pythonFiles\testing_tools\adapter\pytest\_discovery.py", line 44, in discover
raise Exception("pytest discovery failed (exit code {})".format(ec))
Exception: pytest discovery failed (exit code 2)
at ChildProcess.<anonymous> (c:\Users\Zach\.vscode\extensions\ms-python.python-2021.12.1559732655\out\client\extension.js:32:39076)
at Object.onceWrapper (events.js:422:26)
at ChildProcess.emit (events.js:315:20)
at maybeClose (internal/child_process.js:1048:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5)]
conversely, running python -m pytest works fine
oooh powershell has tree, neat. is there a way to include/exclude items? the result is much too big (all the build artifacts etc)
Edit it first?
thats what I'm working on, didn't know if tree had neat commands for pruning/ignoring that would simplify it
Dunno tbh
eeeh, its like this
a/
a/
__init__.py
__main__.py
a.py
tests/
test_a_test.py
setup.py
pytest.ini
oh, there is also a pytest.ini floating around now (asked for help in general to no avail, despite best efforts)
but importantly, just running pytest from the command line works fine
its the testing extension in VSCode that is having the issues it seems
Yeah missing a/a/tests/__init__.py
Ah wait I thought your tests were in a/a
that did it immediately
You probably don't want that
If you have an external test layout it means you need to install your package to test it
If you have an inline test layout it means you don't
I don't think I understand the difference between external and inline in this contect
So your a package isn't installed in the place you're testing it
I tend to prefer inline tests
hmm, putting the folder into a src/ folder as recommended broke the tests immediately
ok, so how do I install my code from the local version, which is evidently something that should be done? instead of testing the files that are currently on your computer? that doesn't make any sense. I've clearly lost the thread at some juncture.
heyo, if I got this
a/
src/
a/
__init__.py
__main__.py
a.py
tests/
__init__.py
test_a_test.py
setup.py
pytest.ini
how do I go about getting my tests to run again?
got it working, yet I feel like I know less now than I did before. thanks for the help though!
if your current working directory is a, then you should be able to just run pytest tests. this is because tests is a python package in the current working directory, and by default python looks for packages in the current working directory. so pytest should be able to just find it
regarding src, you are usually expected to pip install or better pip install -e your code
in this case, if your working dir is a, you can do pip install -e ., because the setup.py is in ., and that indicates the top-level of the "installable thing"
if you really didn't want to pip install it, you would have to add src to PYTHONPATH because src rightly is not a package
so PYTHONPATH=./src pytest tests - but i recommend instead doing pip install -e . to set up your project, so you can just run pytest tests (among other nice things)
I see. Do I need to re-run pip install -e .? And, will this detect issues like messing up a manifest file and consequently a resource not being included, or is that something I just gotta test manually?
(also, thank you, I appreciate the additional context)
huh. my tests run as expected now, but when I try installing the package it fails due to missing an expected file. I thought I understood a MANIFEST.ini enough to include a resource. Is there a way to automate testing that an install on another machine will work?
no, the -e sets up a "link" so that you only have to run it once, and it will always use your current source code. it's basically a tidier version of setting PYTHONPATH; -e is short for --editable
ok, great
if you use pip install -e instead of setting PYTHONPATH, i don't think it will catch a bad manifest file. you might have to do pip install without -e for that. i remember when i first started doing stuff w/ package data and manifest files, i learned the hard way that i had to test without -e before deploying, to make sure i didn't mess up
MANIFEST.in, not MANIFEST.ini. also you need setup(..., include_package_data=True) in setup.py
i don't know about automated testing on another machine other than what CI ("continuous integration") can offer
but you can use Tox or Nox to automate setting up a fresh venv, installing your package in it, and running the test suite
ok I'll add that arg, I had the right file extension thankfully
you can also do that "manually" with build/workflow tools like Make of course, but a lot of people use Tox
re: package data, https://setuptools.pypa.io/en/latest/userguide/datafiles.html
great! I'll go read that over a beer, see if everything comes together
christ if I can get this to work I'll finally have deployed something on pypi lol
of course they don't link to the actual docs that specify how to write a manifest file 🤦♂️
i assume you have seen the guide on https://packaging.python.org ?
The Python Packaging User Guide (PyPUG) is a collection of tutorials and guides for packaging Python software.
they show you how to deploy to pypi using the Twine tool
I'm able to use Twine, and I got stuff deployed to the testpy
but getting something so that some one can do python -m MY_PACKAGE has beeen more difficult
Ok, so I have seen this, but I bounced because it was the third thing I had seen and each did something different!
fair enough
indeed. the "how to create a package" guide material isn't that easy to use or find
(and it didn't really exist at all until very recently)
but it seems like you are there, or mostly there
I'm so damn close I can taste it. I have bounced off this process several times now for a variety of reasons, but at long last it is within my grasp. I think you pointed out the last piece I needed, looking forward to testing it (left to join my partner for a beer, some things gotta wait)
so, thanks! I appreciate the assistance
for sure, good luck w/ this. you might want to ask in #tools-and-devops if you have more packaging questions
oooh good call. this started with a problem with a testing framework and became the next issue that was eating at me lol.
https://github.com/Ksenofanex/stock-management-api/blob/master/api/tests/test_viewsets.py
I've finished writing tests for viewsets/endpoints. First time with these packages, any kind of constructive criticism is welcome.
Can you show the error message?
Hi Friends !!
I am getting error while importing some library...
any guess how to fix ??
This python community is well organized, good foundational tools
I do dot know much yet seems simple the Class can't be imported directly access/loaded into the program from the module ( since the identifier isn't unfound in the syntax). Use proper conventions(identifiers/literal explicitly) when giving the path import command.
hey idk what is unit testing can someone tell me what it is and how its useful?
i wanna learn how to use it if its cool
this book explains it
if to say shortly, it is how to code software fast and in high quality.
any programming of industrial level is requiring testing as necessary requirement
because
imagine horizonal line being time spent on the project and grown size of code base
without testing your code complexity to control it grows in exponential way, until it reaches the peak where your human brain capacities unable to comprehend it
unit testing allows to keep every test code check as an automated test, that does everything for you
allowing you to be not remembering how to make sure the code works
and if it the test breaks, due to granular enough coverage, you can find easily where the error
because tests cover your code in small and high coverages all over the code, it is easier to find bugs, because you are pointed to exact regions in the code where they are
so tests make sure you find most of bugs in 5 seconds or minutes instead of a a whole day
yes yes
ah ok thanks got it
so its like a debugger
pro version
u a welcome.
as small additional bonus, if you write testable code, you are forced to think clean/nice code by design. it helps to avoid you writing bad code.
exactly
Is this the right place to setup and teardown database tables with sqlalchemy?
https://github.com/aryaniyaps/todos/blob/main/backend/tests/conftest.py#L15-L26
backend/tests/conftest.py lines 15 to 26
def pytest_configure(config) -> None:
"""
Setup test suite.
"""
Base.metadata.create_all(engine)
def pytest_unconfigure(config) -> None:
"""
Teardown test suite.
"""
Base.metadata.drop_all(engine)```
@haughty summit why not use fixtures?
I want to try developing using TDD approach, i mainly do web development
Should i test my services first or create a functional test (for an endpoint, e.g. POST /users)
I could use fixtures, but I prefer the hooks for setting up the test suite. I would like to use fixtures to provide dependencies
Hi All, I am facing issues in writing unit test for my flask app. The exact issue is that test files in the unit-test directory is not able to import files from the app folder.
My directory structure:
.
├── Dockerfile
├── README.md
├── app
│ ├── __init__.py
│ ├── api.py
│ └── wsgi.py
├── docker
│ ├── docker-compose.yml
│ └── start.sh
├── requirements.txt
└── unit-test
├── __init__.py
└── test_api.py
Code in unit-test/test_api.py:
import unittest
from app import api
Absolute import throws this error:
from app import api
ModuleNotFoundError: No module named 'app'
I have tried the following after checking a few resources of absolute and relative imports, none of them worked.
from .. import app
error:
from .. import app
ImportError: attempted relative import with no known parent package
I checked a few questions above and someone recommended having _init_.py file in the unit-test folder as well but I already have a blank init.py file there.
Please advise how to fix this error and run unittests.
Are you sure . is where you point out in the diagram?
cd unit-test/
python -m pytest .
..is very different from..
python -m pytest unit-test/
@round igloo hey
ohhh, I understand now. I was doing the first method. If I go to the root directory of the project and run python -m unittest unit-test , the test is running successfully. What would be the reason of failure though in the first option you gave @frigid basalt ?
ops, I got excited. It ran 0 zero test.
If I do python -m unittest unit-test/test_api.py , it fails with the error:
ModuleNotFoundError: No module named 'api'
😦
yes, . is the root of the project.
The reason is because __main__ (where Python is running from) gets placed inside of unit-test meaning that you can't walk out of it for security reasons. Absolute imports also go from __main__, not your project root (Python doesn't know where that is, all it knows is __main__).
Which import is this?
it's an import statement in unit-test/test_api.py to import app folder. api is one of the files in app folder. I added the code in git after a suggestion by @ornate timber for review. link: https://github.com/vaibhavsolanki1193/unittest-help
ok, I have this in unit-test/test_api.py
if __name__ == "__main__":
unittest.main()
Because of this main , the unittest are not able to import app folder? If I remove it though, would unittest class even run?
Do you have that at the bottom or-?
yes, end of the test file. I tried to remove it and ran the python -m unittest unit-test/test_api.py from root folder. Got this error:
File "/path/.pyenv/versions/3.10.0/lib/python3.10/unittest/mock.py", line 1411, in get_original
raise AttributeError(
AttributeError: <function ping at 0x101c6c040> does not have the attribute 'get'
I added the following code unit-test/test_api.py to fix it for now.
import sys
sys.path.append('../app')
If your code resides in /app directory you can append it to PYTHONPATH environment variable, sys.path would work too
:incoming_envelope: :ok_hand: applied mute to @proper wind until <t:1642534637:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
smh
i'm using python 3.9.10 and have started getting deprecation warnings related to distutils (specifically, i think, my package uses marshmallow and the error is DeprecationWarning: distutils Version classes are deprecated.). as far as i can tell, this is preventing me from even running pytest, which is not good. what gives? as someone who couldn't care less about whatever is going on in distutils-land, how do i get back to work easily? any advice? drop a point release to 3.9.9?
maybe this should've gone in a help channel, it's only tangentially related to unit tests, but "marshmallow broke unit testing" is hopefully not just a me thing
a deprecartion warning should be just that: a warning
ie, it should not prevent you from running unit tests
i ended up just adding DeprecationWarning to pytest's warning filter (-W on the command line, etc.); it works. not pleased, but also didn't really want to troubleshoot further so called it a day & opened myself a tracking issue
I use Python and Clojure as my main languages, and I really like the simplicity of clojure.test's "is" and "are" functions which automatically catch errors, etc. However, the unit testing in Python seems much more involved to use: https://docs.python.org/3/library/unittest.html
Is that just because it's object oriented?
Have you considered pytest?
Python doesn't have anonymous functions the same way I think Clojure does (I recognize that line of "is" and "are" functions from JavaScript tests)
yes, it takes inspiration from junit
i agree, pytest will probably feel more comfortable to you coming from clojure
i don't know of any python testing framework that uses the "is" idiom
i am also familiar with it from e.g. JestJS
Thanks! pytest seems much more simple.
I have a very simple code which need to write unit test. I added the raise ValueError in the init.py in order to make sure the unit test will not hit the real method. When running pytest, it errors out because my raise error code. Can some expert helps me to know the way to mock this ,please?
# test_app/__init__.py
from flask_cors import CORS
from test_module import Test_Service
testService = Test_Method()
raise ValueError('unit test should not hit here.')
class App(Flask):
def __init__(self, *args, **kwargs):
super(App, self).__init__(*args, **kwargs)
def create_app():
app = App(__name__)
testService.init_app(app)
CORS(app)
return app
# test_app/tools/utils.py
from test_app import testService
def test_me():
if testService:
return 200
return 100
# tests/tools/test_utils.phy
import unittest
from test_app.tools.utils import test_me
class TestMethods(unittest.TestCase):
def test_me(self):
assert test_me() == 200
if __name__ == '__main__':
unittest.main()
can someone help me this please? ^^^
You want to use this: https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises
Oh, you're using a mix of pytest and unittest
!d pytest.raises
with raises(expected_exception: Union[Type[_E], Tuple[Type[_E], …]], *, ...) → RaisesContext[_E] as excinfo``````py
with raises( ...) → _pytest._code.code.ExceptionInfo[_E] as excinfo```
Assert that a code block/function call raises `expected_exception` or raise a failure exception otherwise.
There's this as well ^
hello I am looking for help with this question I just posted in stack overflow - https://stackoverflow.com/questions/70792589/chromedriver-not-opening-django-development-server. Thanks in advance!
Can any one help me with data scrapping?
I stuck in a problem
Hi all. I am using pytest to write a test suite. I have some code which I want to run before ALL pytests. I put that code in pytest_configure. I want the result of that code to be set in a global variable accessible to all pytests later on. It seems that my global variable gets reset between pytests. Any good way to achieve this?
Session-scoped fixture maybe?
I figured it out. Thanks for the reply though!
Hey someone please help me with this. If I don't solve this for tomorrow I could loose my job https://stackoverflow.com/questions/70818059/how-to-mock-a-class-atribute
I have an object like this:
class Person:
def init(name, age):
self.name = name
self.age = age
self.has_paid = False
def paid(self):
if condition:
has_paid = True...
Can you show the actual code you're using?
I am trying to add a new method to moto but running into funny problems when re-using one of their existing Exception types. can I get some pointers or tips in this channel?
hey guys i have to make a couple of test for my school about a fonction that i created a that test my model, view and url could someone help me ? sorry if my question was wrong/bad
Can someone please help me with setting up test cases with pytest and sqlalchemy?
Here, I am trying to setup a test database connection, and I want to configure my database session to bind to it. However, I cannot seem to decouple it from the engine
My tests also freeze inbetween, I dont know why
https://pypi.org/project/flake8-pytest-style/ Are these good Flake8 rules for Pytest code style
Anyone know good ressources or even just examples or code that uses a proxy model with a treeview to not only format the items to strings but also support filtering by not only regex and straight text, but also comparison to attributes of the content items?
Edit: for PyQt/PySide
I use PySide6 but am happy for examples in either PySide or PyQt and any of the versions.
I'm just gonna assume these are good linter rules
It's subjective, but yes, I think that plugin has good rules and I use it myself. I like that it enables me to consistently enforce a style even for something as subtle as tuple vs list.
i've read Clean Code and TDD (the goat) and now i'm scared to open vscode again for being judged. please help not coded in 5 week
Start small, start from writing unit test of what you are going to write
Tests don't judge, they just point to problems ;b
Who have paypal guys? I really need help
Hi Guys, I need some help with testing. I am writing an application with Clean Architecture and following TDD.
Now I have a test which tests a use case which uses repository to create something in the data store. Now in the test I am using mockito-python for mocking the repository, using factory-boy to generate entity objects that i am using in my application.
Test:
class TestAddGiftCardUseCase(TestCase):
def setUp(self) -> None:
self.gc_repository = mock()
self.use_case = AddGiftCardUseCase(self.gc_repository)
self.gift_card_create_request = GiftCardCreateRequestFactory()
self.gift_card = GiftCardFactory(
redeem_code=self.gift_card_create_request.redeem_code,
date_of_issue=self.gift_card_create_request.date_of_issue,
pin=self.gift_card_create_request.pin,
source=self.gift_card_create_request.source,
denomination=self.gift_card_create_request.denomination,
)
def test_returns_none_when_gift_card_created(self) -> None:
when(self.gc_repository).get_by_redeem_code(
self.gift_card_create_request.redeem_code,
).thenReturn(None)
when(self.gc_repository).create(self.gift_card).thenReturn(None)
self.use_case.create(self.gift_card_create_request)
verify(self.gc_repository).create(self.gift_card)
Factories:
class GiftCardCreateRequestFactory(Factory):
class Meta:
model = GiftCardCreateRequest
redeem_code = FuzzyText(length=14, chars=string.ascii_uppercase)
date_of_issue = FuzzyDate(start_date=date.today())
pin = FuzzyInteger(low=1_000_000_000_000_000, high=9_999_999_999_999_999)
source = FuzzyChoice(["AMAZON", "WOOHOO", "MAGICPIN", "HDFC SMARTBUY"])
denomination = FuzzyInteger(low=1000, high=10000, step=1000)
class GiftCardFactory(Factory):
class Meta:
model = GiftCard
id = LazyFunction(uuid.uuid4)
redeem_code = FuzzyText(length=14, chars=string.ascii_uppercase)
date_of_issue = FuzzyDate(start_date=date.today())
pin = FuzzyInteger(low=1_000_000_000_000_000, high=9_999_999_999_999_999)
timestamp = FuzzyNaiveDateTime(start_dt=datetime.now())
is_used = False
source = FuzzyChoice(["AMAZON", "WOOHOO", "MAGICPIN", "HDFC SMARTBUY"])
denomination = FuzzyChoice([50, 100, 200, 500, 1_000, 2_000, 10_000])
The Use Case:
class AddGiftCardUseCase:
def __init__(self, repository: GiftCardRepository) -> None:
self._repository = repository
def create(self, gift_card_request: GiftCardCreateRequest) -> None:
if self._repository.get_by_redeem_code(gift_card_request.redeem_code):
raise GiftCardAlreadyExists
gift_card = GiftCard(
redeem_code=gift_card_request.redeem_code,
pin=gift_card_request.pin,
date_of_issue=gift_card_request.date_of_issue,
source=gift_card_request.source,
denomination=gift_card_request.denomination,
)
self._repository.create(gift_card)
The Domain Models:
@dataclass(frozen=True)
class GiftCard:
redeem_code: RedeemCode
date_of_issue: date
pin: int
source: str
denomination: Denomination
is_used: bool = field(default=False)
id: GiftCardID = field(default_factory=uuid.uuid4)
timestamp: datetime = field(default_factory=datetime.now)
@property
def date_of_expiry(self) -> date:
return self.date_of_issue.replace(year=self.date_of_issue.year + 1)
@dataclass(frozen=True)
class GiftCardCreateRequest:
redeem_code: RedeemCode
date_of_issue: date
pin: int
source: str
denomination: Denomination
Now the problem is when i run the test, I get this error:
======================================================================
FAIL: test_returns_none_when_gift_card_created (unit.test_usecases.TestAddGiftCardUseCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "GCManager/tests/unit/test_usecases.py", line 56, in test_returns_none_when_gift_card_created
verify(self.gc_repository).create(self.gift_card)
File "Library/Caches/pypoetry/virtualenvs/gcmanager-EE8BmWzo-py3.10/lib/python3.10/site-packages/mockito/invocation.py", line 242, in __call__
self.verification.verify(self, len(matched_invocations))
File "Library/Caches/pypoetry/virtualenvs/gcmanager-EE8BmWzo-py3.10/lib/python3.10/site-packages/mockito/verification.py", line 94, in verify
raise VerificationError(
mockito.verification.VerificationError:
Wanted but not invoked:
create(GiftCard(redeem_code='TYOGRKTNUAMUJA', date_of_issue=datetime.date(2022, 1, 27), pin=5241190185186769, source='WOOHOO', denomination=7000, is_used=False, id=UUID('b2b681ed-1e71-4132-a149-24f634deaca9'), timestamp=datetime.datetime(2022, 1, 27, 19, 20, 44, 319957)))
Instead got:
create(GiftCard(redeem_code='TYOGRKTNUAMUJA', date_of_issue=datetime.date(2022, 1, 27), pin=5241190185186769, source='WOOHOO', denomination=7000, is_used=False, id=UUID('4af5d23f-c3d2-4564-86b3-690e2a061d06'), timestamp=datetime.datetime(2022, 1, 27, 19, 20, 44, 532751)))
The UUID Seems to be different and i think i should patch it but i am not able to figure out how to patch it
I am not able to figure out how do i reference uuid4 so that it returns the uuid i want it to 😦
.
I'm trying to figure out the best way to add testing to an application i just inherited.
I have a main.py and quite a few custom packages.
in the main.py there are a lot of methods some which are already testable and some which will need to be refactored.
I'm somewhat new to unit-testing though i get the gist of it.
My question is when should i use test suites vs test cases vs subtests
Start with the smallest possible test and see how much coverage you get
Then looking at test coverage see what the next best thing to cover is
So i have a general idea on what i want to cover. but I'm a bit thrown off on the difference between using test suites filled with test cases. and test cases filled with sub tests.
guys can anyone explain IN DEPTH HOW SELECTORS change when dev team puts feature flags on an app compared to when it doesn't?
Selectors?
I have a feeling that he asks
How CSS selectors change their path to needed to him DOM objects
when devs disable/enable feature flags in application
for tests written in tools like Selenium
The answer: Unpredictably in any way, HTML/CSS layout can change ;b
The only thing he do, is to write selectors targeting the last DOM objects in best way he can, instead of using absolute paths from the DOM root.
It will still not help if some features were enabled/disabled differently, so the tests can still break depending on different settings
I am having trouble importing a class within a project using VS code. Can someone help me out please
anyone have any experience with using pycharm for coverage testing? I cant seem to get the branch coverage to show up anywhere despite ticking the boxes in the settings.
the only things that seem different are the UUID and microseconds,
Hence, I would suggest to not compare the UUID, and neither the timestamp. At the very least, if a timestamp is a must, dont compare nothing smaller than minutes.
The redeem code along with the pin would be a good enough identifier; justifying the removal of the UUID comparison.
I'm using unittest and I'm trying to figure out how to test a piece of code that returns a False on an exception.
I have tried to use
self.assertRases(ValueError, function_name, arg)
and
with self.assertRaises(ValueError):
func_name(arg)
both create an error that says TypeError: 'bool' object is not callable
If i try
self.assertFalse(func_name(arg))
I get a ValueError
If i do a try except finally in my test case it will work but it still prints an exception and I dont want it to do that.
any ideas?
Sounds like you've got an error in your code somewhere - do you have a boolean variable with the same name as a function that you're trying to call?
try:
return int(var) in some_dict.values()
except Exception as ex:
print('EXCEPTION:', ex)
log.exception(f'EXCEPTION! {ex}')
return False
is it bad practice to not unittest, but just use breakpoints and prints?
They serve different purposes. Breakpoints and prints are fine to get things working. Automated tests are to make sure that you didn't break anything else in the process.
alr
Has anyone ever used pytest along with pytext-xdist to parallelize unit tests across different machines?
has anyone found that github actions macos workers have a process: mdworker-sizing taking up 50-60% of a cpu.
It seems that indexing is enabled for /
is there a way to disable that e.g. with launchctl?
I don't really know - I tried this https://github.com/graingert/distributed/commit/7083777c0b68dbbbd1d9ff3671e4cda52811ab16
seemed to get a slight speedup
like saved 6 minutes on some runs
looks like github is having a problem
Yep
Back up now afaik
I've not heard of mdutil before this
i think i have read about it once before, when i was more interested in customizing my mac
Any tips on making sense of a devilishly complex pytest suite?
Lots of fixtures, some intended to be overridden, some not.
No docs either
how about starting to write new tests
where first ones contain just first fixtures in the chain
and then progress to writing new tests with adding new fixtures from your complex test
until you reach the full state of the test
Exploring the code with tests 😉
Well, I'm trying to write a test 🙂
and I am trying to write an article already second day. I am dev, not a copyrighter ☹️
Can we swap?
It sounds like a plan 
:incoming_envelope: :ok_hand: applied mute to @proper wind until <t:1643913520:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
:incoming_envelope: :ok_hand: applied mute to @pliant lagoon until <t:1643988953:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
Anyone know how / if it's possible to set the log level during pytest tests only for my code instead of setting the global level?
Yeah you can add handlers for tests (assuming that's what the folder is called) and set the log level for that handler
I'm not sure if this will do what I wish, I ended up solving using this
disable_loggers = ['werkzeug']
def pytest_configure():
for logger_name in disable_loggers:
logger = logging.getLogger(logger_name)
logger.disabled = True
I believe that fixture is called in all tests, it disables the logger for the imported third party module so I don't see its logs
I want my logs inside my source to be logged in a certain level, but not third party logs to be logged on that level ( or at all )
So modules outside the tests module to log
Here's how Python Discord sets up their loggers:
https://github.com/python-discord/bot/blob/main/bot/log.py#L45-L85
What are best practises as far as log testing goes? Should I test the entire log line including the expected parameters, including randomly generated ones? should these be inside say an integration test or should there be a specific unit test just for log testing which mocks any dependent objects?
Hmm, you want to test that your application logs things during conditions you test?
yep, even under no specific conditions, when I call a function it always logs something
In my opinion, just testing that the logging happened and that it was of a certain level should be reasonable enough? Overall I wouldn't recommend testing logging though. If logs aren't appearing when they should be, then surely something else must be affected?
but yeah in some conditions,t hat function will log something else say on the ERROR level as well
Or I guess I could have forgotten to insert the log myself? Or someone has removed it
If someone removed a log you will see that in the version control diff, no? Are you perhaps feeding logs somewhere else where you need them to not change?
Sure I can still miss it on the version control diff, I would prefer for an automated and non-human error way of catching it 😄
It seems poor because you now lock how easy it will be to update the logging and improve it.
Simply asserting logging level seems like a nice compromise though
Maybe i can be lenient as you said, assert the level only. but how would you do that exactly?
You'll know that the logging is still there, and that it will trigger the correct response (for example you may hook up Sentry for CRITICAL level logs) - no matter if someone replaces the text
So just look at the specific logger's logs, not all of them
You would play around with a log record https://docs.python.org/3/library/logging.html#logging.LogRecord
And assert that say, 1 log of that level exists?
So create your own handler that simply saves the logging records to a list and then allows you to look at it after the test is done perhaps?
Yup that's what I would opt for personally, not sure if there's some book out there about testing logging 😅
I think it's actually generally recommended to test your logs
More so if it's a critical application feature, say for example if you are required to log all incoming traffic
It's not a requirement in my case but 😄
"I said logging and not logs because they don't matter much, as logs are a detail of implementation.
What I mean is you should test that the action of logging was done. "
I don't want my system to break though and end up with no logs to debug afterwards for example
You could potentially use this as a quick trick: https://docs.python.org/3/library/logging.html#logging.setLogRecordFactory
It seems like it will be called for each log record created so you don't need to create your complete own handler if that's a big pain
Yeah I read that answer, I can agree with that. You want to test that at a certain terrible condition that CRITICAL was logged and a log was sent waking up on-site engineers
If a log is part of your business logic it should be tested, if it is solely used for debugging (and that specific debugging is not part of business logic) then don't test
Is it possible to assert that pytest-httpserver is called or not? e.g.
def do_request():
pass
httpserver.expect_ordered_request(...).respond_with_json(...)
do_request()
httpserver.check_assertions()
this will pass
i don't entirely agree, your logging might be important for error reporting and monitoring for example. that's not business logic as such, but it's important
also if you are developing a library and if you expect the logging to be used by 3rd parties, then it is effectively part of your library's interface
eg the Tornado web framework has a logger for http request handlers which is very useful to enable
I guess it's debatable whether that's business logic (If the only method for error reporting and/or monitoring is the log then I'd argue it is)
<@&831776746206265384> kind of sus
his one of actions requested os.remove("/usr/local/lib/python3.10")
another action os.remove("./Pipfile.lock")
he has malicious intents
ok
Hello someone fill me in about this chat page
I'm starting to kinda dislike pytest fixtures...
you can't "Go to definition" on a fixture, because there's a an implicit dependency
I would much rather import something
wdym?
It would be cool if you annotated the parameter somehow to mark it a fixture
ah
Maybe in my case it's just the case of developers abusing fixtures and making a really complex setup
There's an experiment on this sort of thing in pip install di
I assume that stands for dependency injection?
yes, join me
too much magic
unnecessary
fixtures should be explicitly passed as a decorator
!pypi di
thanks for the recommendation, looks interesting
@pytest.fixture(db=db_fixture)
@pytest.parametrize('i', [1, 2, 3])
def test_do_stuff(db, i):
...
☝️ that's how i wish pytest had done it
I guess a bit of an issue is how you can overwite fixtures though
Explicitly passing the fixture would defeat that
Imho annotations are better here
@suite.tests.append
def do_stuff(db: Annotated[Database, Fixture(db_fixture)]) -> Validate: ...
still has the issue of not ensuring that the types are compatible 🤔
I think what pytest has is just an autowiring dependency injection framework.
so it has kinda the same problems/potential solution
(I guess)
ah you mean you don't know if given Fixture(fn) that fn returns a Database?
hm, fair enough. but then maybe it should be a dynamic global thing instead:
@pytest.parametrize('i', [1, 2, 3])
def test_do_stuff(i):
db = pytest.fixtures['db']
...
that i think would be the lisp approach
fwiw this is also a problem with hypothesis, click, and other such things that inject variables by name
interesting, i haven't seen many good use cases for Annotated (other than attribute/parameter-level docstrings)
I have a question regarding mock & patch in #help-rice if anybody is able to lend a hand.... cheers! #help-rice message
Hi
hello! could get some feedback regarding unittest module
It's best to ask your question rather than ask to ask, also #❓|how-to-get-help
hey, how to implement pytest mocking on database. I'm using asyn mongoDB motor lib. Is there any tutorial? Do you know any tutorial about this topic?
When using respx with pytest to mock http requests, is it a good idea to create one generalized fixture mocking multiple requests, and other more specialized ones used to override the responses for some of the urls?
Currently I have something like:
@pytest.fixture
def mocked_requests():
with respx.mock(assert_all_called=False) as respx_mock:
...
respx.mock(URL).mock(return_value=Response(200, USUAL_RESPONSE))
...
@pytest.fixture
def mocked_bad():
with respx.mock(assert_all_called=False) as respx_mock:
respx.mock(URL).mock(return_value=Response(200, BAD_RESPONSE))
def test_with_bad_response(mocked_bad, mocked_requests):
...
It works fine, but I'm not sure if it's a good practice.
thanks
if it is not a good practice, what is a good practice? 😄
how can I unit test my code witch dependences to external resources?
hi there, who can recommend some materials about testing? it's really hard for me, I understand basics, but can't write the code for function or class
Hypothesis doesn't inject variables by name, fwiw - you have to supply them to the @given(...) decorator.
We've also put a lot of work into type annotations, so you can get static checks for most simple problems 🙂
(with ParamSpec making more possible in 3.10)
I think what they meant is that if you do
@given(x=text())
def test_foo(x: int):
...
``` a type checker won't be able to catch the mistake
I think ParamSpec won't solve this, unfortunately (unless you type text() to return a str). It doesn't let you "wrap" each parameter type in something
You need to run mongodb when you run your tests
There's also stuff like mongita
There is no mongo instance connection from my CI build server 😦
mongita - I will check this out
thanks
Ah, yeah, that won't get caught 😔
Construction and composition of strategies is mostly statically checkable now, though, and there's a steady stream of useful peps (eg ParamSpec + Concatenate lets us precisely annotate the @st.composite decorator)
Well, I don't think it's really an issue. The mistake would be caught as soon as you run the test, so it doesn't cost much
Yeah, it's not a big deal, but if we can support static checks (especially for editor squiggles) I do like to.
indeed, fix error explained what i meant. but yes, that is the style i wish pytest would support!
saaaame, so many fixtures would be more ergonomic as context managers.
But Hyrum's Law is strict, we can't really change it now without breaking things for literally millions of people.
If I had a better solution I'd implement it, but with my pytest-core hat on incremental change (e.g. deprecating common misuses or confusions) is clearly the way to go.
🤞 we never end up with irrecoverable regrets about some core part of Hypothesis' design...
context managers or hypothesis/click-style decorators-that-pass-kwargs
fwiw you could implement it as a new alternative api and keep supporting the old one
but that might be too much work
Best option IMO is to implement it as a downstream plugin which can be "blessed" once it's gone through trial-by-users for a while.
Too much work is the real problem, my backlog is something like a decade fulltime at this point. I might pitch some ideas at the PyCon sprints though...
Hi all,
I should write a test for the rest API with following properties:
- It has REST endpoint: /short/<ARG>.
- can be any combination of exactly two alphanumeric characters, e.g.:
"Ab", "12", "a2". - Returns json with 'uid' key and value of exactly 32 alphanumeric characters,
e.g.: {"uid":"855f938d67b52b5a7eb124320a21a139"}.
Would you please help me? I've not ever written test. how should I test it?
Thanks
You basically need to write code that executes your code. That's what a test is. You pretend you are the consumer/user of your code, then you can run "assert" statements on the results. pip install pytest to get started.
thanks
yo, any links where i can learn about essentials of unittesting in flask ? Most vital stuff only
this looks promising @thick fjord https://stanford-code-the-change-guides.readthedocs.io/en/latest/guide_flask_unit_testing.html
and this: (i run this inside a private browser session so I can read it without paying for a subscription) https://medium.com/analytics-vidhya/how-to-test-flask-applications-aef12ae5181c
Hello all,
I would appreciate it if you could introduce me a useful book regarding unit test(and generally test) in Python.
Thanks,
it is written with examples in C#, but that's not really an issue in my opinion
Thank you. it looks great
Hi I’m looking to learn about TDD. Any books you recommend? Thanks
Technically original book for this goes from Kent Beck
But
Python has its own book
I am not sure which one is better 🤔
I went only through the part of the first book
356 reviews in amazon for Kent Beck
https://www.amazon.com/Test-Driven-Development-Kent-Beck-ebook/dp/B095SQ9WP4
Python is surely fresh one, 2017 year
huh, in good reads, Kent Beck has even 3917 ratings
https://www.goodreads.com/book/show/387190.Test_Driven_Development
Kent Beck book is a bit old, goes to 2000-2002 year.
I should probably read them both and compare 🤔
Awesome, just started reading the Testing Goat, but maybe I read the og book because I can’t go wrong with reading about tests, right?
I liked very much reading Unit testing and best principles from Khorikov book
it allowed me to understand where I should concentrate my testing efforts
before reading the TDD
Ok great, didn’t notice the book. The order of book reading: Unit testing -> The Testing Goat book -> TDD by Kent Beck
it sounds like a good plan
Thanks
hello everyone! is there a way to test class based views in Django with pytest? could someone please provide me with any resources since i can not find any ( i am only seeing functional based views getting tested )?
Thanks!
Hi I’m doing my first project. I think it’s difficult for me to do testing before writing code. Can you please forgive me for not following the Testing Goat?
You must repent.
the problem with unit testing is that most people test units that are too small. i bet you can come up with one reasonable invariant property of your application, right?
(practically yes of course just start and figure everything out as you go)
The testing borg collective
If I write code that works for similar to a calculator. I should write the tests first using pytest. I’m trying to look for basic information to do a basic test on a basic application. The books I’m reading to see intensive for a beginner like myself.
It is soo hard for me to understand the tests. Surely there’s a simple guide on how to get started for testing
when you design your application, try to separate "functionality" from "user interface" as much as possible. that way you can write tests for the core calculator functionality without having to go through the entire user interface
it helps to think of your application as developing a library for yourself, and thenw rapping it
Sure I can do that. I can write a separate file. What can I do after that?
the "core" of your application should be as much "pure functions" as possible, only doing user interface stuff at the "edges"
that way you can just write tests for those pure functions
Awesome I will stick to doing for the script I’m writing. I can just use unitest for now. Apparently it’s not industry standard to use unitest though?
either pytest or unittest is fine. i think unittest might be good to start with, because people do use it. and spending some time with unittest helps make pytest seem better by comparison!
however i think pytest really is better, despite there being a few things i don't totally like about it
fortunately pytest can run unittest test suites too
iirc it doesn't support a couple of the more sophisticated unittest features, but you aren't likely to use those anyway
So what would be the best course of being a better tester. Use pytest?
Just learn this library well?
I appreciate the advice, I’m more confident now
i suggest picking one and learning it
the other thing about unittest is that you don't typically need to worry about "plugins" like you do with pytest
i'd go with unittest to start
Hey @dusty torrent!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
@proper wind using the AAA or 3A test pattern is helpful (Arrange-Act-Assert). Here is an example in pytest:
# ./src/punctuation.py
def remove_punctuation(string: str):
"""Remove all punctuation from a sentence except for spaces"""
return "".join(c for c in string if c.isalnum() or c == " ")
# ./tests/test_punctuation.py
def test_remove_punctuation():
# arrange
input_data = "Hi, this is 1 example."
expected_output = "Hi this is 1 example"
# act
output = remove_punctuation(input_data)
# assert
assert output == expected_output
Getting 0% coverage in sonarqube for python project which used nosetests to create coverage.xml file.
Can anyone help me with it , strongly stucked to it since a week.
What could be the reason for above mentioned query?
First thing would be to check sonar's output; is it consuming the .xml or raising a warning?
Next thing would be; Are the paths in the converage.xml file pointing to the code as defined in your sonar setup? (will sonar find the code from your project layer if it follows the paths). I had an issue with tox while testing an installed library that the paths pointed to tox's venv and not the project files.
It's giving warn in sonar output , mentioning :
WARN: The report '/apps/dftjenkins/jenkins_node/workspace/v_AutomationAuthenticationScript/coverage.xml' seems to be empty, ignoring. '{}'
org.sonar.plugins.python.EmptyReportException: null
Is it an empty file? 
yes , it says it's an empty file
couldn't able to get it why .. It should be with coverage reports
I meant, if you look at that file is it empty?
yes, It says it's empty, shall we connect here?
But nosetests should generate coverage.xml file .. if it tells all test as OK
It should be. I'm not super familiar with nosetest. Are you running it with the --with-xcoverage plugin or generating the coverage report directly with coverage xml?
yes , running with --with-xcoverage plugin
that should generate coverage.xml file
I agree. I'm not sure why it wouldn't. nosetest isn't a tool I've used. 
Can you please elaborate it mpre
Next thing would be; Are the paths in the converage.xml file pointing to the code as defined in your sonar setup? (will sonar find the code from your project layer if it follows the paths).
setup.cfg is created for nosetests , and sonar-project is for sonar reference. I couldn't find any problem within it, could you plz check once!!
[nosetests]
verbose=3
with-xunit=1
xunit-file=nosetests.xml
with-xcoverage=1
cover-package=.
xcoverage-file=coverage.xml
exclude-dir=test
sonar.projectKey=PIN_API_hth
sonar.projectName=PIN_API_hth
sonar.projectVersion=1.0.0
sonar.language=py
sonar.sourceEncoding=UTF-8
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.xunit.reportPaths=nosetests.xml
sonar.python.xunit.skipDetails=false
sonar.sources=backend/orchestrator, backend/worker, backend/worker/Relations.py
sonar.typescript.lcov.reportPaths=coverage/PIN_API/lcov.info
sonar.python.coveragePlugin=cobertura
This is jenkins stage code refering to coverage.xml for sonar
stage ('Test/Sonar') {
steps {
// This specific examples expects that you have a Dockerfile.test that you build, then run to generate test results.
// Since different projects can vary however, you should make sure you use the solution that works best for you.
sh "docker build . -f Dockerfile.test -t python-test:${BUILD_ID}"
sh '''docker run -u 50001255:25 -v "$(pwd)":/app python-test:${BUILD_ID}'''
sh '''sed -i 's|filename="|filename="'"$(pwd)"'/|' coverage.xml'''
sonarScan('Sonar')
}
// Make test results visible in Jenkins UI if the install step completed successfully
post {
success {
junit testResults: 'nosetests.xml', allowEmptyResults: true
}
}
}
A warning is raise from sonar side :
WARN: The report '/apps/dftjenkins/jenkins_node/workspace/v_AutomationAuthenticationScript/coverage.xml' seems to be empty, ignoring. '{}'
org.sonar.plugins.python.EmptyReportException: null
That part doesn't matter right now. You need to figure out why nosetest isn't generating a coverage report first.
nosetests is working fine, I guess so It says below, but creating empty coverage.xml
docker run -u 50001255:25 -v /apps/dftjenkins/jenkins_node/workspace/v_AutomationAuthenticationScript:/app python-test:31
..............................
Ran 30 tests in 4.618s
OK
Yes, but I'm clueless at this moment.. I've given 4 days time to investigate, even I tested few of my thoughts.
cover-package=. does the package directory have a __init__.py in it? I'm clueless as well.
No Preocts.. cover-package=. is considering entire application file/folder. and top of that there is no '
__init__.py'. file
Please let me know , if you get something to resolve this 🙂
do you use kvm?
Hey, has anyone experienced this response didnt redirect as expected: response code was 200 (expected 200)
:incoming_envelope: :ok_hand: applied mute to @fallen moss until <t:1645462800:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
:incoming_envelope: :ok_hand: applied mute to @fallen moss until <t:1645463658:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
Hello,I have a question about tests. I have just created a Python module that allows me to manage docker containers but I have no idea how to write the tests.should I create mocks to simulate the responses of the docker commands or should I let the containers be created during the tests? (this will involve running the tests on a machine with docker)
It'd probably be most repeatable to set the tests up as docker-in-docker
there's some challenge to this but you should only have to solve it one time
you probably shouldn't be setting up mocks to mimic responses of the Docker containers, because then you'll be liable to just end up in a situation where you're testing your mock implementation, not actually testing whether your code does what you think it does to Docker containers
Ok, thank you very much. I am going to see that 🙂
anyone familiar with web automated testing using python & unittest? i need a bit of help, ty
I couldn't able to integrate nosetests coverage.xml with sonarqube scanner. sonar gives status of 0% coverage .
Can anyone help me with it?
Situation is similiar to :
Is there a nice way with pytest to use the same parameters twice, one with the original value and one with a function applied to it? I know I can just modify the list of parameters beforehand, but I am wondering if there is like some magic way to just add a second decorator.