#unit-testing
1 messages ยท Page 24 of 1
in the code snippit i see ccall is using sqlite . I decided on postgres as the better of the two for what im doing
are you hosting this somewhere? Heroku?
i haven't decided where to host this yet . Probably not heroku , i've heard not to host there .
There was a place .. one sec
while looking for where to host the API , there were reasons for why not to .. and i weighed them and made a decision. Havent heard them as explicitly "dont do this, do that" . Just multiple opinions with multiple points
and i forget the reasons . looking for what i decided
i guess it was between heroku and AWS
I need to go soon, also this is bordering on a #web-development convo rather than a #unit-testing one. here are my thoughts:
- Use Flask-SQLAlchemy. Define
db = SQLAlchemy()and have that be at the top level of a file. You do not need to do anything likeglobal dband all that jazz. - You'll benefit from looking at how other people organize their Flask apps to see how to structure everything without having things break a bunch. Here's an example I like: https://github.com/cburmeister/flask-bones
- For testing, I highly highly recommend
pytest-flask-sqlalchemy. It solves a lot of the hardest parts about testing a database.
best of luck with your app! ๐
thanks a lot for the convo .
we'll get into this soonish and update the repo
I am actually learning at the moment how to write code less depended on each other.
Books:
Head first, design patterns.
Clean code in python
does it worth to get with examples in C# even if I know just a bit of python?
yeah, I feel like totally worthy
the philosophy-concepts are totally universal
I think I'm looking more for examples in python to better get hang of it and use it it my code eventually, but yeah..
shrugs.
this books says about unit testing in general
it recommends reading about TDD or whatever you choose after that as next one
it could be the... so recomended TDD in python as next one
the book from Vladimir Khorikov is good for begining, to get started in the fields of testing
Hi I have been trying to mock a class of mine and Im doing this but theres something wrong that Im not sure about, error I get is AssertionError: <MagicMock name='Region.__getitem__()' id='139880814276056'> != 'AAA'
@patch('cloudcast_python_tools.fetch_mws_data.MWS', return_value = None)
@patch('cloudcast_python_tools.fetch_mws_data.Region')
def test_get_region_name(self, mock_python_helper, mock_mws) -> None:
fetch_mws_data = FetchMwsData('test')
mock_python_helper.return_value.airport_code = 'AAA'
region_name = fetch_mws_data.get_region_name(mock_python_helper)
self.assertEqual(region_name, 'AAA')
from bender.mws import MWS
from rip_python_helper.region import Region
class FetchMwsData:
def get_region_name(self, region: Region) -> str:
if not region:
return ''
return region['airport_code']
could it be as simple as: you are setting .airport_code, but then accessing ['airport_code']?
+1 that seems like the most likely solution
@viral rain maybe you're a javascript programmer? in python, region.foo and region["foo"] are not the same thing in general; some libraries allow you to use them interchangeably, but this is a deliberate decision by the library designer and they need to do specific things to implement it.
there is another problem: you forgot to call mock_python_helper
mock_python_helper.return_value.airport_code = 'AAA'
region_name = fetch_mws_data.get_region_name(mock_python_helper())
@patch('cloudcast_python_tools.fetch_mws_data.MWS', autospec=True)
@patch('cloudcast_python_tools.fetch_mws_data.Region', autospec=True)
def test_get_region_name(self, mock_region, mock_mws) -> None:
def _region_getitem(self, key):
return {'airport_code': 'AAA'}[key]
mock_region.__getitem__ = _region_getitem
fetch_mws_data = FetchMwsData('test')
region_name = fetch_mws_data.get_region_name(mock_region)
self.assertEqual(region_name, 'AAA')
maybe like this?
@patch('cloudcast_python_tools.fetch_mws_data.MWS', autospec=True)
@patch('cloudcast_python_tools.fetch_mws_data.Region', autospec=True)
def test_get_region_name(self, mock_region, mock_mws) -> None:
expected_region_name = 'AAA'
def _region_getitem(self, key):
return {'airport_code': expected_region_name}[key]
mock_region.__getitem__ = _region_getitem
fetch_mws_data = FetchMwsData('test')
region_name = fetch_mws_data.get_region_name(mock_region)
self.assertEqual(region_name, expected_region_name)
region_name = fetch_mws_data.get_region_name(None)
self.assertNone(region_name)
@pearl cliff is the autospec = True needed? Also when accessing an attribute of a class which is more preferable. Should I index or use the . operator.
You access attributes with a dot.
The point is that .x and ["x"] are not interchangeable, they do different things.
Ihave a file structure that looks like this CloudCastPythonTools/ src/cloudcast_python_tools/ __init__.py (empty) fetch_mws_data.py table_wiki_page_edit.py test/wiki __init__.py(empty) test_table_wiki_page_edit.py
test_table_wiki_page_edit.py imports from cloudcast_python_tools.table_wiki_page_edit import TableWikiPageEditAndTableWikiPageEdit imports from fetch_mws_data import FetchMwsData how do I initialize my init.py to allow this to work
I am getting this errorfrom fetch_mws_data import FetchMwsData ModuleNotFoundError: No module named 'fetch_mws_data'
I tried to import some stuff into the __init__.py file but Im not sure what to import into it and which __init__.py I should be using
@viral rain from cloudcast_python_tools.fetch_mws_data import FetchMwsData or from .fetch_mws_data import FetchMwsData
I tried that in src/cloudcast_python_tools/__init__.py but it didnt work
@viral rain what happened when you tried it?
When I run the unit test, I get the same no module found error
File "/home/abushark/TestPythonTools/env/CloudcastPythonTools-1.0/runtime/lib/python3.6/site-packages/cloudcast_python_tools/table_wiki_page_edit.py", line 6, in <module>
from fetch_mws_data import FetchMwsData
ModuleNotFoundError: No module named 'fetch_mws_data' ```
@viral rain i gave you 2 examples, that's neither of them
Should I change the one in table_wiki_page_edit.py?
I just added that import to the __init__.py
Okay, I added it to the table_wiki_page_edit.py and it worked
Thanks
at a loss for how to write a first test using pytest for this first project using pytest . The project is already made and i've always done manual testing
only have 2 flask routes so i see flask isn't really that important to test (right away)
thinking about starting a new project just to implement pytest from the get-go
You could start by testing what you find the most tedeous or complex to test manually or the most critical part of your project first. Then new code must be tested before you write anything (TDD) and when you have some time, continue writing tests for the rest of your code base.
What is a good way of "patching" an external API that I access over HTTP? Basically, I want to simulate an API.
With the things I'm using right now, I can just allow for an additional parameter to specify the place to call, and I could specify my test server address (like localhost:42069) and run the requests against my server. But what would I do if I'm using a library doesn't allow such parametrization?
@fiery arrow not much else to do but mock the http client at that point, i think
lots of libraries do this for requests, probably some for aiohttp and httpx
well, that sucks, because my tests will depend on how a particular library is implemented
maybe there's a way to temporarily connect to some sort of proxy?
i think it'll still depend on the http library, unless there's a way to do it at the system level
run a container with some kind of proxy wrapped around it? is that possible?
something like Docker?
i guess, no idea
i have to mock http requests to a 3rd party in one of our work apps, i know that the client library uses requests internally so i'm using https://pypi/project/httmock
i didn't do any in-depth comparison/evaluation, this one was in the edwin jung talk so i figured it was probably good enough for me
(this one https://www.youtube.com/watch?v=Ldlz4V-UCFw)
"Speaker: Edwin Jung
Mocking and patching are powerful techniques for testing, but they can be easily abused, with negative effects on code quality, maintenance, and application architecture. These pain-points can be hard to verbalize, and consequently hard to address. If your unit tests are a PITA, but you cannot explain why, this talk may b...
Yeah i've just gone back to reviewing some of the API front-end code . I said the flask routes weren't that important to test ... i see its an incorrect statement becuase that's exactly from where the user interacts with the API . Accidently passed myself an incorrect value and the API failed. I think it'll make sense when getting back into adding features with refactoring , have primarily been refactoring the structure ... and package-like imports.
I like to patch/investigate bugs with tests: you write a test that reproduce the buggy behavior and refactor your code around that case.
So im hearing you do it proactively . It's just something you do immediately when something breaks "by accident" , but could also break when a user is using it. Havent gotten to that with unittesting modules yet because to test something i first need to know which parts of a unittesting module is used to test the issue . Flask i see has a couple layers to its unit testing.
I investigate what is causing the bug -> reproduce a test scenario to trigger the bug -> patch the bug -> send to production
Sometimes it better to use Integration testing rather than unit test for patching a bug, it all depends.
wonder whether you have examples on github
that's awesome
I applied this into projects that are NDA protected. It's more of an idea than a code recipe.
yeahhh , i want to see it in action from someone i've heard it from . (about the request to see implementation)
commit history and stuff
I think this is a good approach, I try to do it too where possible. It helps ensure you understand the cause of the problem before you apply the fix, and then the test stays to make sure the same problem doesnt come back in the future.
That's kind of like regression testing, except you're using the test to reproduce the bug rather than writing the test after it's already fix.
I suppose the order of those does not matter as far as the term is concerned - just as long as you have the test made.
#help-broccoli subject of having unit tests for whether a postgres database has tables initialized in it . (i've just set up a project on another computer and simply forgot to run the functions that make the tables) . was wondering how to unit test it
#help-broccoli message for returning a better message than sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "stream_live" does not exist
found that theres not a good way to unit test this . Just verify that the tables are there before serving the API to the client
Vcr cassets
Is nice way if you need record your interaction with external source
And just wishing getting same answer from it repeteadly during a test
Looking for whether to test all of it or test none of it . Finding that some tests are generally not as easy to write .. and with the increased complexity , the gains are lower using them . By example, using selenium testing with this flask app is more complex than testing database models .
Just heard it nicely split up into unit testing , functional testing , and end to end testing . Selenium being end to end ... functional being testing from the user perspective, and unit being from the developer perspective. Iโll divide my test files that way
also using the coverage library to generate a report on how well tested the app is and where it can use better testing
For pytest, is it supposed to be installed per-project or something I can just install globally?
poetry provides functionality to define "dev" packages, i.e. packages that are used by the developer and not part of the core functionality of an application/module, is pytest one of those dev packages?
Yes, since it is only used for testing your application by developers, and not for the core functionality of the package
Sure, but I'm still confused on whether or not to install it globally or per-project
I think it won't really matter, but I keep my dependencies per-project in poetry environments
better having locally as it is better practice
but nothing prevents you from installing globally... which I am usually doing in my containers)
I think "test everything or test nothing" are both unnecessary extremes ~ you can just write tests for parts of your app where you think it'll be worth it
some parts can be difficult to test, yes, and arguably some things may not be worth writing tests for
To solve this recently I used a docker-compose file to provision the testing Postgres instance locally (or in CI) and mounted the init.sql script into the container
You have the right idea with keeping it as a dev dependency
I'd install it into the venv with the rest of the project ~ you may still want to have a different version for different projects
it's still a dependency of the project and belongs in the venv
Feeling myself an idiot
TDD with Python...
is written about Django! my main framework)
I should have read it instead of reading another author perhaps)
here: https://www.youtube.com/watch?v=ww1UsGZV8fQ
from 3:47 - 4:15
maybe I'm misunderstanding the speaker, do they really mean that if they have
def foo():
for i in [1, 2, 3]:
yield bar(i)
def bar(i):
return i**2
they are going to patch out bar when testing foo? That seems totally crazy, is there something wrong with me, or maybe I'm misunderstanding?
I'd say that it would depend on what is considered a unit for what you're testing
If you patch out all nested function calls indiscriminately, then you end up a lot of patches and assertions that functions were called (in this case you can check the yield value, but it is more difficult when it's not returned/yielded)
It also creates tightly coupled tests
yeah, I had the idea that unit testing should test on the boundaries of a "unit", i.e. the public interface
I think that was her point but she didn't explain it clearly. Cause she goes on to mention that there are integration tests
So mock nested function calls to avoid increasing the scope of your test to an integration test, I suppose is what she means
But of course not all functions are their own units
i wonder how unit testing can be implemented here #help-carrot message #help-carrot Having an error where the flask app "freezes" after an insert statement to the database using sql alchemy . Doesnt throw an exception , and the program cannot be stopped with shift + pause_break . this sh** is the terminator
it was sql alchemy waiting for a commit()
it makes more sense if bar does nondeterministic and/or expensive i/o
but also some people are more "mock-happy" than others
personally i've started to drift towards less unit testing and more "integration" testing
if it's not part of the public interface, i don't bother unit testing it unless it happens to be a particularly hairy piece of code or i'm about to refactor it
that's partly because i don't necessarily know what the "internal interface" should be when i first write something
too much testing of individual units right at the start of development means lots of wasted time, in my experience
some would argue that this is unit testing, in that the only "units" are public APIs
that makes sense for a library developer, but when you're writing an app, pretty much everything is an internal API
the API boundaries are somewhat arbitrary and fluid
so if you start with integration testing of what you know are firm boundaries (e.g. external-facing HTTP endpoints) then you have a chance for application internals to stabilize
then if/when you start using internals in other parts of the code, you can start forming clearer API boundaries within the application
that's at least how i've been doing things recently and i think it's working very well
The (infuriating) No True Scotsman of testing
Yes, but it is even worse than this. Tests that assume things about internals are actively detrimental because they make it harder to do refactorings
right. my point is (something i haven't seen discussed much at all) is that when you start a project you might not even know what will be "internal" versus "external", so if you just start writing tests for everything you could end up in a bad situation like you describe
Maybe that's what you meant. I just wanted emphasize that you not only spent time that wasn't a benefit in the end, you actually created technical debt. (I spent a lot of time doing this when I first learned about testing)
Indeed I made the same mistake too, and did the opposite of what I said above.
Where I thought every function was a unit so I wrote a test for all of them
To me, this is the real reason why testing is disliked - cause it's really hard to do it right.
Could have been, you know, some famous book by a famous person that caused this confusion maybe...
on the other hand, throwaway tests can be valuable if you have lots of little pieces of difficult logic
but you have to put them in a separate part of the test suite
I don't know which one you're referring to, but maybe that trickled down to where I got the idea from. Maybe I came up with it on my own, cause it's tempting to just go by a concrete definition of a unit. I think programmers tend to want absolutes, if that's the right word. If you suddenly give a more vague definition, it ruins our day.
I think the very popular and often recommended Beck TDD book strongly gives this impression. I don't think you came up with it on your own.
Also, lots of advocates for the test pyramid, which is IMO just wrong
Solid , appreciate the input from experience.
It often depends on the budget of the project and what kind of value tests bring. We work with startups: some are still in the infant stage and have little budget so we do bare minimum (unit tests). Some have taken off and are bigger, they have a bigger budget and now we have unit tests, end-to-end tests and visual integration testing.
I'd argue that bare minimum is integration tests (testing that interactions between units work correctly).
In our case, unit test is the bare minimum. It's a sanity test to prove everything works as intended and it is good to clearly define "being done". Integration testing can be done manually by you and/or the client.
The bare minimum budget level is a pain, in particular if a repeat client of that level leaves that level badly managed
writing a test for a config file to see that it's declared
def test_api_key():
'''
test config.py file exists
test config.py contains a variabled named "api_key"
test variable is defined
check api key is capable of sending a request
'''
#look for file config.py in config/
#call variable "api_key" from config/config.py
#check that the variable is declared
#send a test api request using the API key
probably not the best place to ask but probably the closest,
does postman runner support sub-dictionaries when using a csv file import?
and if so, how do i do it XD
im not sure how you would do this , also not sure what postman runner is . But someone in #python-discussion might be able to help you with this . also opening a help channel makes the question more visible to other users #โ๏ฝhow-to-get-help
@glad plinth
this channel is specific to unit testing . i see postman fits in to the #tools-and-devops channel
my pleasure
@graceful sable postman is often used for testing, fwiw
cursed_patch.py
patches.enter_context(
unittest.mock.patch.object(
subscriber._meta.__class__,
'get_current_api_client',
return_value=api_client,
)
)
i am ashamed to have written this
you know things are already bad when you have an ExitStack of patches and mocks
ok i think i can remove the __class__ part at least, that makes it significantly less weird
I'm using pytest-flask. How can I make several requests within the same test, which each have their own context?
I specifically need flask.g cleared.
Right now I don't see a way, so I'm considering just using the ```py
with flaskr.app.test_client() as client:
with flaskr.app.app_context():
pattern rather than pytest-flask's fixture just for this text case
Ooh never mind I just need with client.application.app_context(): and it works fine with pytest-flask
I guess when I tried that earlier I did something wrong
unit testing is like check every time if it is printing the string you put with no error at all
?
Hey all, I am trying to execute a certain method before my tests are started by pytest.
I have a file called builder.py which creates new python files which are imported in my tests. Since they don't exist when the tests start, I get an import error. I need to run builder.py before tests are started so that the new files can be imported.
Is there a way to do this?
I am not sure on the order of imports when it comes to pytest's test discovery, but try executing the build stuff in a conftest.py
Alternatively, you can just create a shell script that executes the build and then runs pytest.
Have you tried using fixtures
it sounds unusual: what is in these generated Python files?
i wonder , should i be testing code using pytest now , instead of executing the program to see that it works
i see the tests are "falling behind" and this would be a way to bring them up to speed
i heard from Eivl that a great way to write a program is sometimes with the tests first . I have done that , and then updated the main code.. now tests are a bit outdated . I see the slack between updating the two versions is sometimes abrupt , but may be getting the hang of it .
Haven't gotten into Coverage yet , just using pytest
Fixtures are pretty awesome , i haven't understood the logic yet enough to use them but i see they are very powerful .
Was looking into fixtures for populating a fake database for running a collective of functions to use during tests
for now im using simpler tests ... verifying function inputs and variable types
also @maiden pawn i picked up this pytest book i saw suggested by Eivl , as its written for python, and specifically Pytest . https://www.amazon.com/Python-Testing-pytest-Effective-Scalable/dp/1680502409 . I see the book i saw you suggested the other day is about general unittesting principles .. in a variety of languages but primarily the tests are written in C .. or C+ . So i see its something to pick up when ive learned unittesting with pytest a bt more . that book is here, for anyone interested https://www.amazon.com/Unit-Testing-Principles-Practices-Patterns/dp/1617296279
#help-mango message #help-mango issue with testing for quotes in a string .. using raw strings and repr
how do you get pytest to automatically run when you execute a program?
You are probably speaking about Ci/Cd like github actions, gitlab pipeline.
It runs my tests automatically on every commit in the cloud, and reports with mark to every commit, and sends email me if something fails
If you want tests being run even more often...
...IDE has feature to re run them on every code change, but that is a bit extreme in my opinion
Btw, I found that debuging tests with special extension from vs code is the most comfortable way to do it
yes i've heard of this too , having pytest run on commit . I'm looking to run it before executing "the main script"
nice . Wonder what its called
Shrugs. Just make you main script launched with python click library
Or linux makefile
You can set there to run main scipt only if tests returned 0 code (success)
we'll have to set this up. I use Git to push commits
Me too
Not sure. Python testing something. It Is the most popular one there
Testing explorer or smth
It needs changing its settings, to enable pytest mode
Yeah
and then i'll look for how to do this
I wonder what convenience you see the extension adds
it has button to run specific test in debug mode
which enables visual debug from vs code
that's the most convinient feature
plus I can see errors to specific tests
without scrolling them all in the console
anaconda does not work well with Black formatter
i haven't figured out how to use extensions in vs code yet . I'll have to set up the python testing extension another time .
got it installed , not sure how to use it . Its alright running it from a terminal .
got pytest on pre-commit functioning ๐
We have extended the Cerberus validation schema to support some business needs. During our deployment we take our source of truth schema and create new python files with mappings to certain objects.
The files that are built are imported in other files. We need to run our build method before tests are started so that we don't get an import error.
@warm grail why not just build the data structures directly? Why write .py files and then import them?
I think imports happen before fixtures so we would still get import error.
The application is deployed to an AWS Lambda function which runs for a couple seconds per invocation. Building the files during deployment prevents us from having to create the data structures on every invocation.
can you build them during the deploy to your test suite?
I can, but ideally I'd like the build to happen when the test suite is run which I'm not sure how to do.
If pytest has some kind of pre test hook where I could run some setup that would be ideal.
Change your "test suite" command from "pytest" to "build_and_test.sh"
conftest.py did the trick. Thanks @kind meadow Thanks for the suggestions @river pilot
you can break rules, and make imports inside functions (fixtures), ๐
That's very dodgy ๐
But yeah that would work!
Hi, is anyone pytest? I'm having a trouble with saving json files.
When I run:
pytest my_algorithm.py -n auto --benchmark-save=file_name
It creates few json files with run data. I would like to have one single file with all the data. I guess it is because -n auto uses multiple cpu cores and it divide the benchmarks
The pytest-benchmark maintainer is not here, you can find him on the pytest discord
Thanks I'll reach out to them
do you maybe have the invitation link, I can't find any on the internet? Sorry for the trouble
also couldnt find it on disboard , am interested in the link
i wonder how to turn off warning for pytest . In the ini file
also if anyones interested in how to set up pre-commit to run pytest automatically before commit on Git , i'll write the process out here . i did it just yesterday
I'm just doing some algorithm benchmarks for my uni and it keep generating them in different files because I'm using **pytest-xdist (using multiple **cores)
there is a --benchmark-json it creates a single json file but overwrites it
tried this in pytest.ini file [pytest] addopts = -p no:warnings
and there are warning still
#help-bread i'll move this to a help channel to not crowd over issues
needed to move the ini file to the root directory of the project . ( had it inside the tests folder ) . Seeing it needs to be where pytest is called
very convenient
I actually found it a little bit buggy and noisy, and I just run the tests in the terminal. It also lets me customize the tests I run better, I guess.
i like that i can click run and it will run the test and show a green checkmark when the test is successful , and i dont read output
You have to read it when a test fails
true, there is the debug feature for that
Havent used it long . but not sure that i like it . I still run pytest from command line
Using mock library with sql alchemy #help-mushroom message
i definitely prefer dependency injection over patching whenever possible
even if you are injecting a mock
doesn't require knowledge of internals
it's just part of the interface
Dependency injection is key to being able to make good fast tests in OO
I don't really understand why there's an ongoing dispute about DI, maybe someone from "the other side" who can provide his opionion.
is there ever anyone who is opposed to it?
sometimes it might be impractical in a legacy codebase, or require additional thinking or refactoring
there's also sans-io
@untold ore maybe it depends what you mean by Dependency Injection. In the java world, it's very formalized, with frameworks, etc. In Python it's done in a lower-tech way.
Let's say that some object A wants to send message to some other object B;
Then you could either;
- send a message to
Awith an instance ofB
class A:
def foo(self, bar: B):
# do something with bar.
or, you could:
- create an instance of
Bwithin the function.Athat wants to send a message toB.
it needs to send messages to.
class B:
def foo(self):
bar = B()
# do something with bar.
By doing option 1 you make it very easy to substitute the player of the role B with some other thing.
By doing option 2 you increase coupling.
yes. option 1 is what you're talking about, yes?
Option 1 is DI yes.
@untold ore i think of DI as usually the bar argument would be defaulted in some way so that it can be provided if desired (in tests), but doesn't need to be passed explicitly everywhere.
@untold ore where do you see a dispute about DI?
On the internet, and among some colleagues ๐
Hehe
I think it's just a general miscommunication about the definition of DI. Would you say my example I gave was an (albeit simple) example of DI?
Tbh I didn't explore this further with my colleagues as he had just been bashing OO for some minutes straight hehe
I guess it is, though like I said, I think of optionality as an important part of it.
didn't want to add fuel to the fire.
Interesting, I'll dig a bit deeper next time I talk with him ;-)
How do you test the except, the custom exception (ClientError) and assert False is returned in the code below:
s3_client = boto3.client(#...)
try:
s3_client.upload_file(file_path, bucket, object_name)
print("Upload succeed, file name = {}.".format(object_name))
except ClientError as e:
print(e)
return False
I tried this but I dont think Im on the right track
mock_boto3.client.side_effect = mock_client_error
with self.assertRaises(mock_client_error) as _:
result = authorization.upload_file("test", "test", "test")
self.assertFalse(result)
Your own function returns rather than re-raising the exception, so your test should not be asserting it is raised.
Ah makes sense
So all i do is
mock_boto3.client.side_effect = mock_client_error
result = authorization.upload_file("test", "test", "test")
self.assertFalse(result)
Yes
https://docs.pytest.org/en/6.2.x/assert.html
@pytest.mark.xfail(raises=ClientError, strict=True)
def test_f():
f()
test with this decorator, will pass only if it caught exception
They're not using pytest.
Yeah, it's more idiomatic and also more powerful.
Though I don't mind using unittest; I don't think it's terrible
Also, Im not getting false back
Is my use of side_effect correct?
@patch("tickets_trend_dashboard.authorization.boto3")
@patch("tickets_trend_dashboard.authorization.odin_retrieve")
@patch("tickets_trend_dashboard.authorization.odin_material_retrieve")
@patch("tickets_trend_dashboard.authorization.ClientError")
def test_upload_file(
self, mock_client_error, mock_odin_material_retrieve, mock_odin_retrieve, mock_boto3
) -> None:
authorization = Authorization("test", "test", "test")
result = authorization.upload_file("test", "test", "test")
self.assertTrue(result)
mock_boto3.client.side_effect = mock_client_error
result = authorization.upload_file("test", "test", "test")
self.assertFalse(result)
I think you need to be mocking client.upload_file and setting a side effect for it
Ah okay
Right now you set a side effect for client, which means an error will be raised here s3_client = boto3.client(#...)
how do you set one for upload file, would it be mock_boto3.client.upload_file.side_effect = mock_client_error
Yes
Also, I suggest you define a separate test function for each assertion or use a sub test.
If you have unrelated asserts in the same function, it means that if any assert fails, the rest of the asserts below it won't get tested.
Okay will do so
Im still getting issues though with the assert false
Im getting true instead of false
@patch("tickets_trend_dashboard.authorization.boto3")
@patch("tickets_trend_dashboard.authorization.odin_retrieve")
@patch("tickets_trend_dashboard.authorization.odin_material_retrieve")
@patch("tickets_trend_dashboard.authorization.ClientError")
def test_upload_file_exception(
self, mock_client_error, mock_odin_material_retrieve, mock_odin_retrieve, mock_boto3
) -> None:
authorization = Authorization("test", "test", "test")
mock_boto3.client.upload_file.side_effect = mock_client_error
result = authorization.upload_file("test", "test", "test")
self.assertFalse(result)
def upload_file(self, file_path: str, bucket: str, object_name: str) -> bool:
(access_key, secret_key) = self.__retrieve_odin_material(self.material_name)
s3_client = boto3.client(
"s3", aws_access_key_id=access_key, aws_secret_access_key=secret_key
)
try:
s3_client.upload_file(file_path, bucket, object_name)
print("Upload succeed, file name = {}.".format(object_name))
except ClientError as e:
print(e)
return False
return True
It might not be picking up the side effect as an exception since it's a mock
Is there a good reason for you to be mocking/patching the exception?
Can you not just do side_effect = botocore.exceptions.ClientError?
Theres no good reason to mocking the exception. I just thought thats the best way
ill try what you sent
A good reason behind mocking it would be that I dont need to worry about how to construct the exception
I'm creating a bot and one of the features is to reply greeting messages automatically, for example: Good morning, good afternoon and good night. I'm also capturing when there are repeated vowels in the message, example: Goooood mooooorning and is working perfectly.
But I would like to know how to test these cases where there are repeated vowels without having this hardcoded in my test.
Also because I do not care about the amount of repeated characters, for me it is even cool not to know what was the input, I need to test only the behavior.
Any suggestions?
@pytest.mark.asyncio
@pytest.mark.parametrize(
"message_content",
[
"Good Morning",
"good morning",
"Good Afternoon",
"good afternoon",
"Good Night",
"good night",
# Here's the important part. I don't wanna to have this things:
"goooooooooooood morning",
"goood afteeeernooon",
"gooooood niiiiight"
# etc...
],
)
async def test_should_reply_when_message_contains_only_greetings(
mocker,
message_content,
):
message = mocker.AsyncMock()
message.echo = False
message.content = message_content
await GreetingsReply().event_message(message)
message.channel.send.assert_called_once_with(f"{message_content} for you too! TwitchUnity")
you could write a function that takes two params: a string, and a number n. it will find all vowels in the string, and multiply them by n.
or maybe just some vowels?
using this function, it'd be easy to parametrize your test with the base strings ("good morning") and a for-loop that would generate the prolonged versions
i'm not sure whether it'd be possible to plug that into pytest.parametrize somehow, but you could just have the for-loop within the test function and generate the strings there
for me it is even cool not to know what was the input
have you heard of hypothesis? https://hypothesis.readthedocs.io/en/latest/
it helps you parametrize your tests by generating input data (in this example, it could provide the n to use when multiplying the vowels)
a crude example:
In [15]: vowels = ["e"] # List all supported vowels.
In [16]: def multiply_vowels(base_string, n):
...: chars = list(base_string)
...: return "".join(char * (n if char in vowels else 1) for char in chars)
...:
In [19]: for n in range(1, 5):
...: print(multiply_vowels("elephant", n))
...:
elephant
eeleephant
eeeleeephant
eeeeleeeephant
Nice. I also do not know if you can use this with the pytest.parametrize but maybe I can create a fixture to return a list of possible cases, created dynamically.
I just didn't want to have this hardcoded ๐
I don't remember hearing anything about it, but I liked it. Thank you very much, gonna be very usefull
a fixture would probably work yeah, or just have the for-loop in your test function if you're not planning to re-use it elsewhere
no worries
Would this be the right channel to ask about getting started using pytest or unittest for integration testing or should I claim a help channel?
I think this is the right place
Ok thanks.
I would like to start to do system integration tests to automate parts of integration tests and since pytest already has test discovery and execution. Is that the right way to start or are there better alternatives.
The system is not Python based but actuated through a network API
I am guessing the pytest.fixtures could be used for setting up and disconnecting/cleaning network connections
So basically my question is am I on the right track or am I missing something obvious.
Are there known issues with the logger package on a Mac (pyhton Python 3.7.9)
I use the package at work but I just notice it behaves unexpected on my machine (pic related, I expect an info log - and I'd also like to see a logger name. I found one, two SO threads on logger not printing issues, but none of the solutions work here
@light whale never had this problem and can't reproduce (on a mac), but don't use the system python installation for anything. use homebrew or pyenv to install it. also in the future it helps a lot if you post your code as text, not a screenshot.
!codeblock see below
Here's how to format Python code on Discord:
```py
print('Hello world!')
```
These are backticks, not quotes. Check this out if you can't find the backtick key.
!e ```python
import logging
logging.basicConfig(
level=logging.INFO,
format='%(levelname)s:%(name)s:%(message)s'
)
logger = logging.getLogger(name)
print('x')
logger.info('HELLO')
logger.warning('ALERT')
print('y')
@pearl cliff :white_check_mark: Your eval job has completed with return code 0.
001 | x
002 | INFO:__main__:HELLO
003 | WARNING:__main__:ALERT
004 | y
also this isn't #unit-testing related (although i assume you found this problem in the course of writing some tests)
Thanks for the response.
It's the anaconda's python. Recent mac.
Not sure where logging stuff should go (unit testing seemed closest in theme)
anaconda shouldn't be materially different from any other python build in this sense
weird
yeah donno, I'll stick with print for the time being. Thx anyhow
I do not feel very qualified to answer but since no one else did; yes I believe using pytest could work for this
I've never used it to test a completely separate system (only Python code living in the same repo), but I do not see why what you describe wouldn't work
Thanks ๐๐
FWIW we use cypress for this at my job
this is reasonable, yes
what did you want to know about it?
i strongly favor logging if you plan to use this code repeatedly. print is fine for one-off scripts of course
Thx
Ok will just ask here:
I have a fixture that I want to change parameters of the fixture based on my test setup.
Right now I have to hard code in the fixture which data I am using.
How do I do this the right way?
!stats
environment variables? config file?
what is your preferred library for logging?
I use the one in the standard library
https://pypi.org/project/eliot/ there is also this, i only tried it once
I guess I should use it too then.
The only issue I had about it when I just first tried it... it doubled msgs outputed to stdout
hopefully I'll be able to solve this issue this time
I heard about Sentry as alternative
all righty
You probably assigned 2 stdout handlers to the same logger
good time as anything. I like starting my morning with trying to setup new things for me rightly
at last I wish having comfortable debugging with something more than print
pprint is nice too though
How to use the command cuz I'm not sure
you type commands like this into your windows command prompt. if your tests are located in a file called test_myapp.py, you would type py -m unittest test_myapp.py
py aka py.exe is the windows "launcher" for python, -m unittest means "run the unittest module"
Ok thx so much
In my application, I have a variable that contains a path to a directory,
SOME_DIR = Path(__file__).parent
My tests will call some code that will import this SOME_DIR but I want SOME_DIR to point to a different location during tests. I use pytest and found pytest-mock. I see there's a way to patch return_value but since SOME_DIR is not a method, I'm lost. Any guidance?
can you can't you patch my_module.SOME_DIR to be a different object?
i'm not sure about pytest-mock, but in unittest i'd do patch('my_module.SOME_DIR', new=test_dir)
Will try that @pearl cliff ! Thanks
I've got a pretty unit-testy question in #help-apple, if anyone has some spare time I'd really appreciate it: #help-apple message
!commands
Hey guys. Just wanting to ask if anyone here has had expereince trying to do TDD with embedded/hardware-interfacing systems? I ask because my job is to design automation of hardware, and Im wanting to do TDD but not really sure how I should go about it. I know mocking's a thing but don't cant really find any help with specifics to hardware
thanks in advance
I have attempted something similar, but I wasn't able to really find any emulators which would work well enough for what I needed. In some cases, you can just implement some files in the header the HW provider, but if registries are being manipulated, it doesn't really work
!commands
Good day, I wanted to know if anybody has any idea on how I would go about unit testing a UI? Our prof asked us to when making our own calculator apps, but I don't know what to actually test on the UI?
user interactions, that all things are clickable and move you to pages with expected text, login, registration, payments and e.t.c. work
as a choice it can be done fully in Pytest + Selenium
perhaps it can be tested with frontend javascript testing libraries, I dunno. Selenium is python answer for that.
Thanks! I'll try and take a look with Selenium.
Um. We spoke perhaps about different UI
I accidentally gave answer for web dev
If your code in python for user interaction logic, selenium is not needed
It needs pytest only
To check that user actions like
2+7=5
And etc
Whatever user actions can be possible... test them ;)
does anyone here know how to set username + password for proxies (selenium firefox)
There's a book about doing embedded TDD from pragprog, which uses this library http://www.throwtheswitch.org/unity. It uses C, but the concepts crossover to python. The basic idea is to fake out the hardware, and to layer the application such that calls to the hardware are easy to swap out between fake and real boards/devices during testing (this is what I do) . You could also look at Brian Okken's work on python testing. His job is working with hardware, so he may have some specific insight for you.
is it possible to call fixtures from pytest_generate_tests?
anyway, I am trying to parametrize my test with dynamic data, loaded from db
Hi, sorry if this isnt the right channel for this, but the issue im having is that when I try to run my code through pycharm, it runs perfectly fine, however, if I use pyinstaller and try running it that way, my program opens and closes immediately
if I try to "open with python 3.9" the same issue occurs
I believe it may be a problem with ktinker
How about using virtual env
Storing dependecies in requirements.txt
Launching with recreated venv?
In fact, you are probably already using inbuilt into pycharm
And that what confuses you
Since your global python is not having same things
yeahh the issue was kinda smth like that, I was able to fix it, thanks for responding!
Python
Can anyone suggest a way of running behave tess in parallel?
It seems like there are no existing frameworks, closes suggestion i've found is
Hi, i'm trying make my unit tests run in PyCharm. They worked before I added more packages to my project. Where can I get help with this? It is most likely a rookie mistake, but I don't really understand the usemodel very well.
what is going wrong?
Anyone have a good toy/simple python project that:
- Has unit tests
- Has typechecking
- Involves setting up and testing with a database
- CI: Preferably GitHub actions
It feels like there are so many ways to do this so I have analysis paralysis
not sure at which level exactly, but pytest in django handles auto setting up and tearing down testing database on its own, without any line of code
I have everything you mentioned, but it is a terribly bad project, where I made a lot of fuck ups
at least I made horrible decisions regarding database model there
typechecking: mypy
github actions: yeah too, to run unit tests and auto build and deploy its documentation to github pages
Sources Root.
thanks for the offer to help. I tried to refactor my project to add some additional packages. before the changes I could run my unit tests from PyCharm . after the changes, PyCharm highlights correctly, but when I try to launch the unit tests, it cannot find any of the identifiers. I notice that the command line PyCharm creates for launching the tests does not include any path to indicate where the source code is.
Honestly, the error could be 1000 different things. my directory structure might be wrong, or PyCharm might not be configured correctly, or my init.py files might be wrong. I don't really understand what init.py is supposed to contain.
Here is a link to the public repo: https://gitlab.lrde.epita.fr/jnewton/python-rte/-/tree/dir-struct-reorg
Here is the command line PyCharm creates for running the tests:
/Users/jnewton/Repos/python-rte/venv/bin/python "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --path /Users/jnewton/Repos/python-rte/pyrte/tests/genus_tests.py
But my source code is in subdirectories of /Users/jnewton/Repos/python-rte/pyrte. /Users/jnewton/Repos/python-rte/pyrte is marked as Sources Root.
Here is the diagnostic I get when trying to run the tests.
/Users/jnewton/Repos/python-rte/venv/bin/python "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --target tests.genus_tests.GenusCase
Testing started at 11:35 ...
Launching unittests with arguments python -m unittest tests.genus_tests.GenusCase in /Users/jnewton/Repos/python-rte/pyrte/genus
Traceback (most recent call last):
File "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py", line 35, in <module>
sys.exit(main(argv=args, module=None, testRunner=unittestpy.TeamcityTestRunner, buffer=not JB_DISABLE_BUFFERING))
"/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py", line 154, in loadTestsFromName
module = __import__(module_name)
File "/Users/jnewton/Repos/python-rte/pyrte/tests/__init__.py", line 1, in <module>
from .genus_tests import *
File "/Users/jnewton/Repos/python-rte/pyrte/tests/genus_tests.py", line 26, in <module>
from pyrte.genus import *
File "/Users/jnewton/Repos/python-rte/pyrte/genus/__init__.py", line 26, in <module>
from .s_and import SAnd
File "/Users/jnewton/Repos/python-rte/pyrte/genus/s_and.py", line 47, in <module>
class SAnd(SCombination):
NameError: name 'SCombination' is not defined
Process finished with exit code 1
@radiant python a python "package" (a directory with an __init__.py in it) is really just a module that can contain other modules
so pyrte is a package, because it has an __init__.py file in it
setup.py should not be part of the package that you distribute
so it should be one level up, next to README.md
likewise, it's atypical to include tests as part of the package that end-users install, although it's not totally rare either
also, by default and by convention unittest looks for files with the form test_*.py, classes with the form class Test*, and methods with the form def test_*
you can configure unittest to look for different names, but it might be easier to use the defaults until you get it working smoothly
moreover, you are using absolute imports, so those need to start at the top level package name
if your top level package is pyrte, then you need to write from pyrte.rte.r_rte import Rte, not from rte.r_rte import Rte
since it looks like you're a lisp user, think of setup.py as analogous to your asd file. it serves the same purpose
in fact, setuptools is pretty much analogous to asdf. while pip is analogous to quicklisp/ultralisp.
so my recommendation for file structure is something like this:
./python-rte
.gitignore
LICENSE
README.md
setup.py
doc/
...
pyrte/
__init__.py
genus/
__init__.py
...
rte/
__init__.py
...
it's perfectly normal to have empty __init__.py files
your setup.py looks fine, although i recommend reformatting to follow the usual python code style, and you can remove install_requires=[] because the list is empty
and then you would change your imports from rte.foo to pyrte.rte.foo
you can use pycharm to assist you with that import change as follows:
- move
pyrte/genusandpyrte/rteto./genusand./rte - right-click on
./genusin the sidebar, select the "refactor" submenu, then click "move". move it back topyrte/ - repeat for
./rte
pycharm should automatically update the imported module names from rte to pyrte.rte
kind of a hack but should work
also, unittest.TestCase has a lot of helpful assertFoo methods that can produce better error messages when test fail
self.assertEqual(fixed_point(0, (lambda x: x), (lambda x, y: x == y)), 0)
self.assertEqual(fixed_point(0, (lambda x: x // 2), (lambda x, y: x == y)), 0)
see here for the full list: https://docs.python.org/3/library/unittest.html#assert-methods
@radiant python happy to help with additional questions if you have any, just ping me
!rules 5
5. Do not provide or request help on projects that may break laws, breach terms of services, or are malicious or inappropriate.
Sorry but why is that illegal?
it's not illegal, but it almost certainly breaches the terms of service of any site that uses a captcha
and it might be illegal depending on your legal jurisdiction
to protect this server from liability, we can't help with it
You can disable you captcha in unit tests
!e
n = 1
while True:
n = n * 2
print(n)
@proper wind :x: Your eval job has completed with return code 143 (SIGTERM).
001 | 2
002 | 4
003 | 8
004 | 16
005 | 32
006 | 64
007 | 128
008 | 256
009 | 512
010 | 1024
011 | 2048
... (truncated - too many lines)
Full output: too long to upload
!e
print(',no')
I'm thinking of building some automated testing of a web app APIs & its website - actual UI testing I'll set up with Cypress, but for APIs and a few other things I'd like to test with Python, for the non-API stuff I'd want to e.g. make sure some server-side rendering things replace certain tags correctly always, and preferably have this thing be fast enough to run locally regularly, and easy enough to set up that I can run it in CI + periodically, it wouldn't hurt if the same tests could be used for load testing later, oh and supporting (but not requiring) FastAPI / OpenAPI spec it exports could be a nice thing
so I've thought about using locust - but there doesn't seem to be an easy way to complete a single full run of all the tests and then abort, and most of the time I wouldn't want to be running an actual load test
apiritif seems interesting, but doesn't seem like it's particularly well known so could be full of gotchas https://github.com/Blazemeter/apiritif
I'm not sure I like writing test cases in yaml for tavern
anything else I should consider looking at?
I got a question about where to draw the line between unit and integration tests.
Say I have
class MyManager:
def __init__(component_one: SomeClass, component_two: SomeClass, component_three: SomeClass):
self.component_one = component_one
self.component_two = component_two
self.component_three = component_three
def set_state(state: dict) -> None:
self.component_one.set_state(state["one"])
self.component_two.set_state(state["two"])
self.component_two.set_state(state["three"])
def get_state() -> dict:
s_one = self.component_one.get_state()
s_two = self.component_two.get_state()
s_three = self.component_three.get_state()
return dict(one=s_one, two=s_two, three=s_three)
What would be a unit-test for set_state and what would be an integration test here?
In a unit-test I would just use mock the components and assert that their set_statemethod was called, I suppose (To make sure this method always calls set_state for every component)?
While for an integration test I would use actual components and assert that the actual state is equal to the state I set in the test?
"integration testing" is basically calling actual implementations of your software with database, api calls, and everything, unit testing is basically anything that can work without depending on any external systems but generally you want to "unit test" - small "units" of the code, as in not something like
retcode = run_everything()
assert(retcode == 0)
but your unit tests can definitely use actual components
if you have in-memory state, you will typically want to reset that state between tests
Okay, so its fine, even for unit tests, to assume that the underlying methods/classes are functioning correctly?
"integration testing" is about how well your software "integrates" with other software - be it web browsers, databases, other pieces of software, etc.
well you typically shouldn't assume much, you test it, by running the code in your tests
I would of course have unittests for the called methods as well
so e.g.
def test_manager():
mgr = Manager()
state = {...} # TODO
mgr.set_state(state)
assert mgr.get_state() == state
or something
I see, thanks
generally what I try to do is at least have a unit test on every major branch of the code - as in different results that can happen, say trying to register a new user - you test successful registration, one where the password is invalid, one where the username is already in use, and such
.. but beyond that you might want to write test-cases for every "if" if you have the chance - it's a good goal, but often a bit too much in real world projects
generally I try to limit the amount of mocks in my unit tests to the bare minimum to make them work offline without external dependencies
Yeah I am actually doing that right now by using pycoverage.
I like the percentages to hit 100%
80% is typically great
As my app can run offline anyway that's not too much of an issue for me
I'm just glad I don't have to do image-matching tests
which the library Im using has done for me already ,luckily
one issue people can run into with excessive mocking is that they don't actually test the components being used, they just test a component, and then mock it in every other test, so it could blow up all the time in real use but they would never know
I'm using pytests.parameterize to add every distinct combination of parameters for my mocks/classes
So I hope I can avoid that
the other side of the coin is when people don't mock enough and test a bit too aggressively and tests take too long to run for people to run them regularly ๐
generally not a big issue in smaller projects
My biggest issue with testing time is that one of my libraries takes ~7 seconds to load
Which is very awkward, especially when starting the app
what library is that
ah yeah, a lot of the data analytics etc. libraries tend to be .. a bit annoying to work with
I'm only using it to downsample 2-d image so I might be better off writing my own implementation of that, honestly
but yeah, at least when running all the tests at once with pytest you only pay the initialization cost once
Thanks for your time
One more question though: Do you write tests for functions that "don't do anything" e.g, they only call some other libraries methods (that were already tested), nothing else?
Maybe testing that the function always calls these methods makes sense? To avoid future edits from accidentally changing the function?
not quite sure what you mean
but yes, I add tests to things that seem pretty solid, because one reason I implement tests is to ensure it continues to work in the future when someone else modifies something
and that "someone else" is often me after I've forgotten the specifics of the project
seems I might be able to use schematesis maybe for the openapi support but it seems it's a bit too heavily tied to the openapi
anyone to know ways to install a project to a friends computer with all the same modules?
if you're using pip you can dump all the current packages into a requirements file using pip freeze > requirements.txt then on your friend's computer you can run pip install -r requirements.txt (assuming requirements.txt is in the current working directory) to install the packages in the requirements file
@jade spade
perfect! Thank you very much my friend
is there a way to test GUI applications?
for example, if I need to test the user making an account through the UI
is the frontend even tested?
even better would be to use poetry
frontend testing always depends on the frontend in question - you can typically find some in the documentation for the GUI library if there are any options present
I agree, Poetry is seamless
a must pickup in my opinion
Im curious, what is the explanation behind pytest-cov showing non-0% values for modules that I didn't write tests for?
Afaik coverage reports work by checking what LOC were executed by the tests, no? Then all not tested modules that are NOT referenced by tests in any way, shape or form should be 0%
u perform testing on the function that are bound to the events by emulating the UI events too
Can we perform the unit testing for security configuration clasa
i see
I'm using PyQt5, going to look rn for any testing features
seems for PyQt5 there is a QTest library
from PyQt5.QtTest import QTest is a starting point for that it seems
also pytest-qt might help https://pypi.org/project/pytest-qt/
u will need to write tests urself mostlty and launching the events explicitly
Going to look into it, many thanks. This helps a lot.
I started writing tests for my hobby projects. Due to past experience with Java (JUnit testing), I find the default unittest more intuitive than Pytest. I don't need to google as much to find out the correct syntax with unittest. Am I slowing down my growth by using unittest instead of Pytest? Any opinions?
pytest offers much more power.
use pytest as it uses assert and not defined functions and also u can write custom checkers and also fixtures .
class Interval:
"""All real numbers between two points on a real line."""
def __init__(self, bound_1: Union[int, float], bound_2: Union[int, float]):
if not is_number(bound_1):
raise TypeError("bound_1 must be an int or a float.")
...
...
class IntervalTest(unittest.TestCase):
def test_non_number_for_bound_1(self):
self.assertRaises(Interval("abc", 1), TypeError)
I expect this test to pass. However, it fails saying
Traceback (most recent call last):
File "c:\Users\urkch\AppData\Local\Programs\Python\Python_Projects\Exercism\python\go-counting\go_counting.py", line 39, in test_non_number_for_bound_1
self.assertRaises(Interval("abc", 1), ValueError)
File "c:\Users\urkch\AppData\Local\Programs\Python\Python_Projects\Exercism\python\go-counting\go_counting.py", line 21, in __init__
raise TypeError("bound_1 must be an int or a float.")
TypeError: bound_1 must be an int or a float.
TypeError: bound_1 must be an int or a float.
Perhaps I'm not using it correctly.
hello
What's best practices for patch any filename's constant ? I try this but i have an error (no such file) with last test.
@fixture(autouse=True)
def resolv(self, tmpdir_factory):
resolv_file = tmpdir_factory.mktemp("conf").join("resolv.conf")
with patch("initbox.RESOLV", resolv_file.strpath):
yield
or
id_resolv_file, resolv_file = mkstemp(suffix=".conf")
@patch("initbox.RESOLV", resolv_file)
class TestResolv:
def setup(self):
...
bound_1 is "abc", you are passing 1 into bound_2, so it won't pass, as "abc" is not a integer/float
the 1st one keeps the temporary file scoped within the test itself, so i think that's a good idea in this case
I have a simple test for a flask view that renders a template. It just tests the return code is 200. The problem is that the JS and CSS is webpacked, but I don't build the bundles in CI. Therefore, the template renderer cannot find those static files and the test fails.
How do I approach fixing this? Do I patch Flask's static file resolving mechanism? Do I use pyfakefs to create a fake file? Do I check in dummy files and re-route flask to them if I detect a special test config env var is set? Do I build the webpack bundles in CI?
I'd rather just skip this test at this point as it isn't really valuable to begin with.
I don't want to build webpack bundles in CI cause it's gonna slow down CI and the bundles wouldn't be used for anything but that one test.
I already build the bundle when I build the Docker image in CI, so that can already tell me if the webpack build would succeed.
I expect the __init__ to raise TypeError when passing a non-number for bound_1. It seems like it is raising that error. However, the test/assertion is failing.
Basically, I want to assert that Interval("abc", 1) raises a TypeError.
Apparently I need to use a context manager for assertRaises. Why?
class IntervalTest(unittest.TestCase):
def test_non_number_for_bound_1(self):
with self.assertRaises(TypeError):
Interval("abc", 1)
Why can't I do
class IntervalTest(unittest.TestCase):
def test_non_number_for_bound_1(self):
self.assertRaises(TypeError, Interval("abc", 1))
?
You don't have to use it as a context manager
class IntervalTest(unittest.TestCase):
def test_non_number_for_bound_1(self):
self.assertRaises(TypeError, Interval, "abc", 1)
You can't do it the way you tried, because you instantiate the class before the assert gets called. Therefore, it doesn't have a chance to catch the exception - the exception will have already been raised before the assert is even called.
Great explanation. It looks like I can do
self.assertRaises(Exception, Func, Args)
like you showed.
I there, Is the very first time that I use pytest to make some unit test.
I'm trying to test a class method that call a function:
class MccGenerator:
def __init__(self):
self.getXml = XmlService().getXML()
def mccCalc(self): --> I'm trying to test this method
return mcc.calculator(self.getXml)
mcc.calculator(self.getxml) in the background contact a consumer Kafka, make some rest call, some calculations and return an output like "A3" or "C9".
In my test I need to mock this value, because I want to prevent that mcc.calculator(self.getxml) make some http request and, instead, I want check that MccGenerator.mccCalc(self) is executed.
In my test_main.py, I've tried something like:
class TestMain:
def test_mccgenerator(mocker):
mccGenerator = MccGenerator()
mocker.patch("mcc.calculator", return_value=True)
assert mcc.calculator() == "A3"
mccGenerator.asser_is_called()
But without success.
How can solve this?
Thanks in advance
why do you patch it with mock
is it requesting some external resource not under your control?
@maiden pawn No, but when I run test it fail always because call mcc.calculator() that trigger all other http request.
What I only need is to test that MccGenerator.mccCalc(self) is called and its output is something like "A3", "B9", ecc...
anyway, look for magic!
class MccGenerator:
def __init__(self, calculator = mcc.calculator):
self.getXml = XmlService().getXML()
self.calculator = calculator
def mccCalc(self): #I'm trying to test this method
return self.calculator(self.getXml)
all is left in test, to replace default value with self made mock ;b
mccGenerator = MccGenerator(calculator=MyMock)
you can replace xmlservice too if you want
So all I need is to add a variable inside class init, my test has no mistake??? ๐ฒ
well yeah. not exactly sure what you are testing then ๐
testing just a mock logic looks a bit useless ๐
@maiden pawn mcc.calculator(self.getXml) is a function where its prameter (self.getXml) is a result of a message consumed from Kafka, which provide some information that it used to make an http request that return an xml in string. At this point mcc.calculator() get this xml, parse it with xml.element.tree and with some algorithms extract a score like "A3", "B9", from the xml provided.
I need, in some way, to skip all this process when I test MccGenerator.mccCalc, or everytime I'll try to test it will fail because of kafka, http request and xml.element.tree.
getxml function makes http request?
@maiden pawn yep
don't mock calculator then
mock getxml, with your own mock to receive example of answer from http request
or record interaction with vcr library
vcr library makes automatedly remembered last http request and imitates it later
quite easy to use
https://github.com/kevin1024/vcrpy
if you'll go with vcr
the point of mocking to replace only uncontrolled or badly controlled external dependencies.
only your getxml as I can see is uncontrolled dependency
@maiden pawn k thanks for the hints. Now using your previous suggestion:
class MccGenerator: def __init__(self, calculator = mcc.calculator): self.getXml = XmlService().getXML() self.calculator = calculator def mccCalc(self): #I'm trying to test this method return self.calculator(self.getXml)all is left in test, to replace default value with self made mock ;b
mccGenerator = MccGenerator(calculator=MyMock)
my test fail with this message:
ERROR Test/test_main.py - kafka.errors.NoBrokersAvailable: NoBrokersAvailable
maybe because the test trigger the kafka process
btw, I am raising dependency like that
in my dev PC with docker compose
makes sure to test my program against almost real dependencies
if it is possible, just raise your own kafka too perhaps
ok, thanks a lot
hello everyone, does anyone know if there is a software to benchmark the speed of a python program ?
You can do it manually
check out the timeit module
Yeah, that can help
ok thank you, but there is no tools like performances tab of chrome html inspector but for python ?
It doesn't provide that detailed of a report
For eg the timeit.timeit function just returns the amount of time it takes to run the function
yeah i know, but i ask to know if betters ways exists
ok thank you
https://julien.danjou.info/guide-to-python-profiling-cprofile-concrete-case-carbonara/
https://pypi.org/project/line-profiler/
https://pypi.org/project/pyperf/
that what i search, thank you
In Django, I have a celery task that calls an API, serialize the result and put it in the DB. What would be the optimal way of implementing that so that I can unittest the serializing and import to the DB without always triggering a call to the API? I run my tests manually and CI/CD pipelines.
I need some advice on how to test my application, there's basically 2 things that im unsure about:
- How do I test a file-parser (like extracting data from hdf-files)?
- Should I create a mock object mimicking every field (data+header) of the file? This might be quite annoying and would need testing in itself.
- Should I just test the file-parser with files that I currently have (size up to 5GB)? This would limit me in testing possible edge-cases that my files don't cover and I would have to upload possibly 10s or 100s of GB.
- How do I test JupyterNotebook-only parts of my programm? E.g., when running a command of my application in the JupyterNotebook, a server will be started in the background and some synced data will be displayed in the notebook-cell.
- Should I write a "testing"-ipynb that I somehow run whenever I run the tests? Would that work?
- Not sure about my options here
For testing my own parsers, my current approach is to create the test files myself - if it's text that's straightforward and you can add the elements, otherwise you could look for another program creating them you want to be compatible with, and craft a file that features all the cases. A 5gb file doesn't seem that useful since it'd just repeat the same test over and over.
Something you can do is pit different parts of your code against each other with roundtrip tests - take a data set, save it to a file and then parse and check it recovers the original data exactly.
For testing the notebook part, you could fall back to such a manual test, perhaps writing in the notebook the expected results. Or you could try mocking the bits of the API your code touches, and try to verify the results there.
It also does sound like there's command line tools for HDF, maybe you could construct samples with those.
I am curious if other people have suggestions for testing parsing of complex formats, where you can't easily split it into small valid test cases.
Does pytest.mark.asyncio cause conflicts with event loops?
I have a module which uses asyncpg, I am testing it using pytest-asyncio to test it, when I run the tests I always get a asyncpg.exceptions._base.InterfaceError but when I remove the pytest.mark.asyncio decorator and run the function using asyncio.get_event_loop().run_until_complete I get no errors and it works as expected.
The only thing I can think of is the pytest.mark.asyncio decorator is causing conflicts with the event loops
Definitely seems like itโs not as trivial as I hoped to test all that. Especially since my parser does some abstraction of the File and throws away unnecessary stuff, so Iโll have to figure out how to do the testing nicely. I think Iโll inevitably have to write a script that at least creates a detailed Mock of my file so that I can test all ifs-and-whens. Cheers
hello guys how do i input md5 hashes? or find them at all and is it safe to use an md5 hash generator online


Thanks ;)
reading good book and reached unit testing level.
by accident I did the most right mocks already.
the best mocks for dependencies are.... dockerized locally dependencies ;b
https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-the-shell-executor
hmm, I just disabled in CI tests which required other containers-dependencies to run.
Perhaps to try putting into CI, docker execution commands, to run dependencies in CI as well, that would be perfect
Does anyone have experience using pytest-asyncio and asyncpg?
JupyterNotebook-only parts of my program
what parts of your program are notebook only? what does that look like?
also, +1 for the recommendation of generating "controlled" test files and asserting that they can be read correctly
I think the functions that I was worried about don't actually need to be tested from a notebook, instead I can just use a standard bokeh-server.
I was just majorly confused after trying to load external resources into a notebook programmatically.
you can use nbconvert to run the notebook "hands-free"
Good day python dev's.
My unit test cases are getting passed on pycharm ide env but failing when i run using tox file. Im kind of new to tox way of running test cases.
Any suggestions would help?
PS: Im using moto package to mock aws s3 swrvices for testing.
Wow, nice stuff, thanks
failing how? error?
assertion errors, the test cases are passing in python ide
But when run in tox file, all test cases failed with assertion errors
Does anyone have experience using pytest-asyncio and asyncpg?
I'm having issues using pytest-asyncio and asyncpg

@low temple can you show your code and the full traceback? you should probably be using asyncio.run in most cases anyway, but yes it's possible that there are 2 event loops conflicting
for what it's worth i have no idea how pytest-asyncio works
The full question #databases message
I asked the question in #databases because I thought it was a problem with asyncpg
weird
try it with asyncio.run maybe?
probably won't fix it but
oh never mind, i see pytest-asyncio is the problem, not running it without pytest
I tried doing that, when I change my code from pool = asyncio.get_event_loop().run_until_complete(asyncpg.create_pool(**kwargs)) to pool = asyncio.run(asyncpg.create_pool(**kwargs)) I get powershell ValueError: a coroutine was expected, got <asyncpg.pool.Pool object at 0x0000025D7B52CE10>
Wait
Hold on
I didn't realize you were creating a pool outside the test
That is one probable source of the issue with pytest
Is create_pool actually a coroutine function?
wait ill look at the docs for it
wait
the docs show examples of it being awaited
but in the source code it isnt coro
i see, the Pool itself is probably await-able
ok, ill not asyncio.run that then
yep, look at Pool.__await__
however there are issues here
once the pool is initialized you probably can't re-initialize it later
does pytest have async fixtures? you might need something like that if you really want to re-use the pool across your test suite
otherwise you probably have to make 1 pool per test
Thanks for the information :)
I don't think that I can, because my module shares the same pool
Where can I find materials to practice my skills in testing? Google finds only theory and some general tips instead of practice tasks.
@glad rock practice by writing tests for your own programs
My programs are primitive to the point, where I'm just ashamed to write tests for them.
that's part of the exercise
make your code testable
hi pytest fans, any users of pytest-bdd here? I'm looking at options around making bdd scenarios dependant on others
ive got some tests that validate a clean data import process, but then i'd like a bunch more tests to use the imported data
and rather than have the second set tear down and reimport, seems okay to lean on what's there already
This is the first time I've actually heard of BDD ๐
man I guess we have moved on from DDD
I'm a bdd fan!
basically anything that means something is under tests is better than not ๐
i'm going with my second scenarios will use the same steps from the first as background (run once)
Thanks, I did that and it works
. But isn't making a new pool for each test inefficient?
Yes, but testing is about making sure things work right moreso than they are about running as fast as possible
if you have a huge test suite that is so slow it impacts developer velocity, then you should start trying to optimize
Python really has some nasty easter eggs
What is the correct way to monkeypatch an imported function?
main.py
from somepkg.subpkg import afunc
class MyClass:
def do_stuff(self):
afunc()
test_main.py
import pytest
import MyClass
@pytest.fixture()
def mock_myclass(monkeypatch):
monkeypatch.setattr("somepkg.subpkg.afunc", lambda: print("patched"))
return MyClass()
def test_do_stuff(mock_myclass):
mock_myclass.do_stuff() # calls afunc not my lambda
Doesnt work
I dont want to change my non-test code just to avoid this, is there a way?
I think this is the common issue of patching the source rather than patching what imports it
You need to patch main.afunc
Also, I've not seen monkeypatch used for testing. I tend to see pytest-mock instead
I assume monkeypatch is some fixture provided by a library. i don't really know
<@&831776746206265384>
Oh it's gone
This explains the problem in more detail
I recommend reading it https://docs.python.org/3/library/unittest.mock.html#where-to-patch
Thank you, ill give it a look
Guys
I have an API that has a route X that digests webhooks coming from Hubspot
How can I test it ?
Because I need to mock the request from hubspot & validate it
And I'm not entirely sure of how I'll do that
@proper wind you could start your application listening on localhost + some free port, then make requests with fake data to your hubspot endpoint
the tornado web framework has a convenience unittest class to do this, maybe you can take inspiration from their implementation: https://www.tornadoweb.org/en/stable/_modules/tornado/testing.html#AsyncHTTPTestCase
That's what I did, i just made fake data for it.
But i'll have a look at tornado
Thanks a lot @pearl cliff
i don't recommend using tornado in new applications @proper wind , i just wanted to show it as an example of how to set up a test server
it's not that tornado is bad, but there are other choices that i think are easier to use
i haven't used chalice, but keep using what you are using
tornado isn't bad either. mostly i just think it has some ugly interfaces that resemble "old school" python too much
Yeah it's too late to change anyway
Thank you!
How can I omit files such that pytest does not include them in coverage
I tried omit = file.py but its not working
did you try py.test --ignore=dir ?
you can do it multiple times to ignore multiple directories
And have a look here https://docs.pytest.org/en/6.2.x/customize.html
Ill try that
did it work ?
Hey @maiden pawn!
It looks like you tried to attach file type(s) that we do not allow (). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a.
Feel free to ask in #community-meta if you think this is a mistake.
just have file .coveragerc in your main folder with omitted folder/file names
[run]
omit = venv/*
scripts/*
scripts.py
commands/*
mocks.py
I have a question which may be a tad simplistic:
What is currently the "go-to" mocking framework in python?
I've really been liking java's mockito and found some pytest fixtures to mimic that behaviour, but figured that there might be more native python tools available, too.
as far as I tried... unittest for mocks is more than enough, MagicalMocks can be fine used with pytest at the same time
but at the same time if you need patching, better to use pytest-mock library I guess
I also record and mock requests with vcr though
I m not super really into mocks though, in my opinion making spy(mocking the thing with just functions/classes without additional libraries) is more reliable
Heyy
my team and i need to test our web browser
rn we gotta test the searching part
any suggestions on libraries to use?
def loadPage(self):
url = QtCore.QUrl.fromUserInput(self.addressBar.text())
search = self.addressBar.text()
search.replace(' ', '+')
if url.isValid():
self.webEngineView.load(url)
else:
self.webEngineView.load(QtCore.QUrl(
f'https://www.google.com/search?q={search}'))``` actually testing this
i use unittest and unittest.mock. i believe there is pytest-mock if you want to use unittest.mock within pytest.
pytest also has a built-in fixture for monkeypatching: https://docs.pytest.org/en/latest/how-to/monkeypatch.html
How can I do it?

!exec
print(1)
I am in Django Rest Framework
and I need to write test that makes sure that my cookies behave right
what's the right thing to use for sesional request testing?
How to mock calling requests.get (popular requests pypi package's get) inside the function get_track_duration which is located in utils.py?
Order of calling ^
When I use @mock.patch("radio.utils.get_track_duration.requests.get") decorator, pytest shout at me with _ ModuleNotFoundError: No module named 'radio.utils.get_track_duration'; 'radio.utils' is not a package_
Regarding Mock an item where it is used, not where it came from, I should use @mock.patch("radio.api.routes.get_track_duration.requests.get"). However, the same result ๐ฆ
@burnt whale that picture you made is a beauty. thank you for it
the mock path you want to use depneds on how you import requests in radio.utils
if you have
import requests
then you'll want
@mock.patch('radio.utils.requests.get')
that said, you need to have the import at the top of the module. if it's in the function, or lazily loaded, that won't work. if you do something like that, you will need to make the library to use for requests a function argument or some hacky magic like that.
any fans of pytest-bdd here? I'm going crazy trying to use @tags on scenarios and features, and still have tests making there way into my filter pytest commands
i've a couple of feature files, tagged with @first, so when i run pytest -k "second" it wont discover and run them, but theres a few features it just keeps running every time (and they're super slow)
i think its cos i'm step sharing with another test.py file
oh i think -k is the wrong thing, i need -m
becuase of course the word second appears in the my scenario titles marked with @first
is it possible to get which port is taken by django testserver (which is created during tests run)
basically I am writing test where I to make sessional request to secondary app, and then I try request to current app
if there a fine way to make request to secondary app with keeping cookies between those requests, it would be fine too
Unfortunately, in utils.py there is more than one function (which is called during my test) using requests.get.
And the mock you have proposed obviously works (I had written it before) but I have to distinguish mocks because of various url which those functions (and requests.get then) use ๐ข
Maybe requests-mock solves my problem ๐ค
consider using vcr
it records first time you try to request certain url and mocks its automatically every other time with automatically giving you the right answer
it has relatively simple usage
import vcr
path = "vcr_cassets/path_to_your_record_name_which_can_contain_which_resourse_you_request.yaml"
with vcr.use_cassette(path):
requests.get("make your request")
i see, okay hmmm
Hi I need some help trying to mock patch a function used inside a class' init
class TestApp4GInputHandler(TestCase):
@mock.patch.object(App4GInputHandler, '__init__.get_mobile_broadband_host', return_value='4g_host')
def test___init__(self, mobile_host):
print(mobile_host)
self.assertEqual(App4GInputHandler.__init__(mobile_host), '4g_host')
this is the code, App4GInputHandler is the class, and inside the init i've used a function get_mobile_broadband_host which I want to test
But when I run the test I just get this exception
Anyone who knows if I'm doing something wrong?
Update: I tried to patch the test where the function get_mobile_broadband_host was defined instead and this works for some reason
class TestApp4GInputHandler(TestCase):
@mock.patch.object(AppGlobalConfigsManager, 'get_mobile_broadband_host', return_value='4g_host')
def test___init__(self, mobile_host):
print(mobile_host)
self.assertEqual(AppGlobalConfigsManager.get_mobile_broadband_host(mobile_host), '4g_host')
the way I understand how I should define this path in the decorator it should be in the file that the function is being used and not defined
get_mobile_broadband_host is defined in AppGlobalConfigsManager. So now doing this test for my App4GInputHandler like this which I'm not sure is correct tbh??
Because the get_mobile_broadband_host is actually being called in the init_ for the App4GInputHandler class
this works because it's defined on the AppGlobalConfigsManager, you can't mock away something used in a function, what you need to mock the reference used to it
hello! how would I explain a colleague that unit testing is a good thing and should be done for our project instead of some general tests, which "cover everything in one go"?
Unit Testing Principles, Patterns and Practices shows you how to refine your existing unit tests by implementing modern best practices. Youโll learn to spot which tests are performing, which need refactoring, and which need to be deleted entirely! Upgrade your testing suite with new testing styles, good patterns, and reliable automated testing.
you know, you can go overboard in unit testing too? So not sure who out of you right without having your code
just read the book I gues
it tells best practices behind testing
thanks @maiden pawn
So a reference to get_mobile_broadband_host, which is used in App4GInputHandler - problem is I get that exception saying the path does not have attribute get_mobile_broadband_host which is obviously not correct since I'm using it to in init_. I can't pinpoint where I'm going wrong about this, maybe I should just not test this?
can you paste the full path you're using and the traceback?
from unittest import TestCase
from unittest import TestCase, mock
from unittest.mock import Mock
from src.mvc.controllers.handlers.App4GInputHandler import App4GInputHandler
from src.mvc.controllers.managers.configs.AppGlobalConfigsManager import AppGlobalConfigsManager
class TestApp4GInputHandler(TestCase):
@mock.patch.object(App4GInputHandler, '__init__.get_mobile_broadband_host', return_value='4g_host')
def test___init__(self, mobile_host):
print(mobile_host)
self.assertEqual(App4GInputHandler.__init__(mobile_host), '4g_host')
So I import the class, and in the patch i define the path for init_.get_mobile_broadband_host
and this is the full traceback
@proper wind I'm sorry for the late reply :( Can you try removing the __init__. for the mocked path like this:
@mock.patch.object(App4GInputHandler, 'get_mobile_broadband_host', return_value='4g_host')
def test___init__(self, mobile_host):
print(mobile_host)
self.assertEqual(App4GInputHandler.__init__(mobile_host), '4g_host')
no worries, it's ok i'm just looking occasionally when i get an answer :p but it's still the same problem here's the traceback
hmm okay that confuses me a bit
wait no, I think I understand. that's not a method defined on the class, right? you import it into the module where the class is defined
so you will need to mock the get_mobile_broadband_host function imported into the module
path_to_module.get_mobile_broadband_host
where path_to_module is the module name where class App4GInputHandler is defined
It's used to define a variable inside the App4GInputHandler class
the function get_mobile_broadband_host is defined in another class (AppGlobalConfigsManager)
okay, i see, now you pass in the global_configs_manager to App4GInputHandler here. that means you need to mock the method get_mobile_broadband_host of the instance of global_configs_manager you're passing in. But in the test case you posted above, you only gave a single argument (mobile_host) to App4GInputHandler . Was that a different class?
Sorry for delayed answer. But yeah I think you're on to something, it wants three arguments of course for the init... but how do I actually pass three variables one model, global_configs_manager, and db_manager
I'm currently integrating StripeAPI into a Django project. I normally do TDD, but being unable to test stuff that depends on an API is really frustrating. Any tips, resources or advices on what could/should be done??
as far as I know, stripe offers testing account by default when you register
considering that they use frontend part to start the process, I guess all you need just to add something like Selenium to your tests
that should be the easiest path
Is it possible making the test by default not running in pytest, only if the mark is specified
oh yeah it is possible with skipif
Same here. There is stripe-mock (https://github.com/stripe/stripe-mock) which can be useful. but ultimately I found it not ideal for unit testing since it doesn't implement everything perfectly, and I use too many edge cases in Stripe. I ended up just creating a stripeapi module, and encapsulated all code that talks to the stripe api into that, and I mock that whole module out for the rest of my TDD work - then I test that encapsulated module separately against the real stripe API using dev mode API keys.
mb_limit = 8 * 1024 * 1024
if value and value.size > mb_limit:
raise ValidationError('Image file size is over 8 MB. Please resize the image or upload another.')
``` Hi, guys I have this validator in my Django project, the problem is that I have no idea how can I write a test for it
I have put the validator in my model
which testing framework are you using
I hope pytest? ๐
well, it can be done in unittest too, I am just less familiar with it
unittest i think
You could create a model object, then put a value with a size over mb_limit and assert that it raises an error using with self.assertRaises: # create your object and assign it a value whos size is > mb_limit IIRC
okay but my model uses file that is uploaded from the user, how can i simulate this?
i mean to create the model i'll need to set the image=to something (where i don't know what to set it to)
Use a file that would raise the error and load it in your tests.
I have this view ```@login_required()
def create_photo(request):
if request.method == 'POST':
form = PhotoForm(request.POST, request.FILES)
if form.is_valid():
# automatically detects the logged in user
photo = form.save(commit=False)
photo.posted_by = request.user
photo.save()
return redirect('list photos')
else:
form = PhotoForm()
context = {
'form': form
}
return render(request, 'create_photo.html', context)```
and im writing this test which i have no idea what im doing if i gotta be honest
self.client.login(username='john', password='johnpassword')
data = {
'image':self.image,
'posted_by':self.user,
'category':self.category,
'posted_at':timezone.now
}
response = self.client.post(reverse('create photo'), data)
self.assertEqual(Photo.objects.count(), 2)```
the problem is this post doesn't create the object, what am i doing wrong
im trying to write the test only for the post part before the else
and there is 2 because i have crated 1 photo object in teh setUp method
maybe you can split the create_photo function up into two -- one that handles the POST, and one that handles GET and other verbs
then have separate tests for each, of course
well its possible but i have already done quite of the logic and it will mess the whole stuff if i start to refactor it like so
refactoring may well be worth it if it makes testing easier. Your call, of course
i think i could narrow it, when i debugged i saw that my image wasn't passing through self.client.post and this made the form invalid
also im getting this in form.errors -> {'image': <ErrorList, len() = 1>, 'category': <ErrorList, len() = 1>}
which arguments to pass I'm not sure, it depends on whether you can create them in your test without problems or not :(
Using pytest, is there a way to force one file of tests to run before the other?
also, do the tests go alpha-numericly (in terms of file name)
then a possible solution would just be to start the file name with 1 (?)
Do your tests depend on order of execution to function properly or are you just trying to prioritise displaying results of some tests over others
I don't recall reading anything in the docs that states there is a guarantee for any particular order of execution, but maybe I missed it.
the tests consist of making http calls which put, get, and update data into/from a database
so i need to put first, and then get/update
Tests shouldn't rely on state generated by other tests. If you want to test a delete, then populate the db with mock data and then call delete.
ok
still, though
i need to know which ID each thing is, and ID is auto-generated by incrementing by one
For each test you start with an empty db, so the ID will increment from 0. If you insert 2 records as mock data then you know the IDs will be 0 and 1 in the same order.
i cant start with an empty db
Why not? Are you using your production db for testing?
i would like to make the tests public
the way it works is that the DB is created, and then the user has the option of running the tests
Sorry I am not following how that would interfere
all g (sorry for being uclear)
because the user would likely not want to re-create the entire db because it costs money
The database that's used by your actual application should be separate from the one used by tests. They can co-exist. A single running instance of an RDBMS such as postgres can have multiple separate databases inside it.
that still would not work in my case
Depending on the architecture of your app you may need to spin up a new local instance of e.g. postgres just for testing, if your actual db is on a different server.
the HTTP calls code which interacts with specific tables in the db
Yeah you can patch the db connection your app uses while testing so the app is re-routed to the test db rather than the real one. Then your tests can populate the db with the data needed to perform each specific test.
i dont think that is really an option in my case, unfortunately
thank you so much for your help, though!!
Hi, I am from Argentina, I speak Spanish
You're welcome. It's standard to mock out dependencies like databases. For an example, see Django. It creates a test database for you - it's quite convenient.
thank you!
i'm using MySQL in this case
Django is a web framework, to be clear. I am just referring to their bundled testing utilities.
ohh, my bad
thanks!! ill try to look into that
Well it's not meant as a suggestion for something that you can use (unless you happen to be writing a web app). I used it as an example of how a popular library deals with the sort of problem you're facing.
got it
thanks so much again!!!
perhaps by using test generator(parametrization with generator) there is possibility of guarantee of tests orders
or may be even regular parametrization would be enough
well, you can certainly launch particular file of tests by writing
pytest path-to-file-with-tests
or even particular test with
pytest -k even-partial-name-of-test-function
Aye sorry, of course the class needs arguments that I know of, I left this for another time and started on something else, ty for the help! :p
Quick question, a function that fetchall rows from a database, does that need to be tested using mocking or is it not relevant? Cause obviously I can do without with some rows inserted and then performing a particular query on something. But say I delete a row which has elements that I used in the test, then the test would obviously not pass. Is it therefore necessary to just mock it straight away?
It's common to create the elements one uses in a test as part of the setup and removing them as part of the teardown
Another common way is to ensure a expected dataset and converging it to the expected state
Ok so to the first, i can make a setupclass, insert some rows, and then in the teardownclass delete these rows. I'm not sure about the second method - so mocking is not something relevant at all?
Mocking is typically an error prone pain when your dB layer is tightly integrated
Personally I try to avoid it
imo if you can test against an actual database, you should
especially once you start writing big/complicated queries, there's no other way to test that
anyone know the magic incantation for Boolean vars in py test-bdd step defs?
I have {apples:d} apples is a number for instance
Is there any way to find which pytest invoked the code ?
which is hte best testing framework for Django testing, unittest or pytest, and what are the major differences if there are any
defining "best" is subjective. But by far, pytest is good testing framework which support of lot of useful plugins to extend the functionality.
yay for pytest
pytest allows your code tests being more DRY
its fixtures are quite comfortable, or at least I don't remember multiple fixture usage in unittest
and I just like that most of pytest features implemented at decorator level
it looks a bit more pythonic in my opinion
and easier to use
plus you can run pytest tests in multi core mode! which is faster.
and the most importantly...
pytest gives you full backward compatibility with unittest
so you can be having transition at your own temp, step by step from unittest to pytest
Hi, is there a chat for automation testing with python?
this is the channel for automated testing in general ๐
the name is inaccurate but effective, just like in programming
oh I see maybe i should try pytest
hey guys do you use some package or smth when creating models for testing, I saw some video where you can fill the data required for your model with some 3rd party package (or library not sure) and override the thing that you need to test
I have a test that fail when I try to perform an assertEqual on an invalid database query where I expect an exception. It obviously fails because the exception is raised before I get to the assertion, but is there no way around that?
awesome, thank you
in unittest you can use https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises
when im running my tests as a whole I get a integrity error, but when i run it 1 by 1 they pass wtf? any idea why this happens
from a database? it's probably because the tests are doing conflicting things in the database
idk, it says that my unique constraint has failed but i dont see any reason to do so
ok i just fixed it I guess
changed Profile.objects.create(user=self.user) to Profile(user=self.user) and then save no idea how this fixes it tho ๐
Regarding using pytest fixtures:
I currently have a fixture in a "conftest.py" file that connects to a db, yields the db connection & cursor, and then closes those up. I plan on having a few test files with many tests in each that use the connection/cursor
I want to create a function that removes a given ID from the db. Let's call this clean_up(). This requires access to the db connection object and the cursor.
All the test files will require this function.
The best way I can think of implementing this is to make global variables for the connection & cursor which are initialized in one function in each file and then make a function for each test file called clean_up().
I feel like there's gotta be a cleaner/more pythonic way to do this (and yea - only have a few months of experience in py ๐ )
Any help is much appreciated!!
think i kinda figured out what I want to do... but new (similar) question:
how do i run a function AFTER all the tests in a file?
if you're using pytest: a hacky way would be to create a high-level "fixture" that has a cleanup action; run the function in that action
guys, i wrote my project using sqlite database, and wrote my test which covered everything and its working fine, my question is if i change to postgresql will this have any effect on the tests (integration and unit)
yep
postgres and sqlite have different APIs (I think), they certainly have different "dialects" of SQL, and you have to do a bunch more stuff to even "talk to" a postgres database (e.g., provide a hostname, username, and password)
can you tell me or point me to some info, what I'll need to configure and where to use my tests with PostgreSQL
their docs are suprisingly-not-bad
waaaay better than MySQL e.g.
definitely possible
when I made first run of tests when transitioned from sqlite to postgresql
I had them broken because sqlite did not enforce constratints
characters limits to a field and e.t.c.
if youre using some kind of ORM, then this might not be a bigger problem than adding a few authentication stuff
but it doesnt look like youre using any ORM
oh it's about a Django project, forgot to mention ๐
Then the only changes you have to make should be the DATABASES setting
awesome, I thought so, but wasn't quite sure
thank you for your time spending on my questions ๐
does anyone have any recommendation for learning about testing? Tutorials don't seem to cover it very well and any testing help I come across assumes you know what you're doing.
found this video extremely helpful to follow along with. https://www.youtube.com/watch?v=6tNS--WetLI
In this Python Programming Tutorial, we will be learning how to unit-test our code using the unittest module. Unit testing will allow you to be more comfortable with refactoring and knowing whether or not your updates broke any of your existing code. Unit testing is a must on any large projects and is used by all major companies. Not only that, ...
Favorite module to stub an API? Doesn't need to be fancy, I just want to provide basic responses. It's for stubbing Stripe API calls
it depends... do you want to stub out the python library? or the actual network API?
for the former, hard to go wrong with unittest.mock
for the latter, there are a lot of choices and i'd be curious too if there's a "best" one
i've used httmock before
What about https://github.com/stripe/stripe-mock?
haven't worked with it, stripe isn't available in my country for businesses sadly
every client library should be sans-io
and every remote API needs a schema!
how many thousands of hours are wasted around the world every day because people have to manually mock all kinds of stuff
It's not quite as elegant as that
The sans-io part is basically a state machine
You basically query a "next action" from the client, and the client returns some representation of the i/o action you are supposed to take
Then you do whatever you want with it, and send a result back to the client
It unfortunately doesn't work well with generators because you can't send something without also yielding something, unless you have two yields internally and that makes for an ugly API as well as ugly and fragile internals with lots of error checking
If you're writing a client for a REST API there is almost no reason to make those requests "inside" the client
just tell me the URL, the request body, and the headers i need. then i will use my own damn http client
the sans-io part would look like this:
class HttpRequest:
...
class HttpResponse:
...
class SomethingDomainSpecific:
...
class MyClient:
def __init__(self, access_token):
self.access_token = access_token
def request_foo(self) -> HttpRequest:
...
def request_bar(self) -> HttpRequest:
...
def request_quux(self) -> HttpRequest:
...
def handle_response(self, resp: HttpResponse) -> SomethingDomainSpecific:
...
and the io part would look like this, e.g. for httpx:
import httpx
from my_client_sansio import HttpRequest, HttpResponse, MyClient, SomethingDomainSpecific
def httpx_send_request(http_client: httpx.Client, request: HttpRequest) -> HttpResponse:
...
def request_foo(api_client: MyClient) -> SomethingDomainSpecific:
request = api_client.request_foo()
response = httpx_send_request(request)
return api_client.handle_response(response)
once i started doing this, i never wanted to go back to "internal" i/o
the only downside is not having standard HttpRequest and HttpResponse types, or standard functions to convert from httpx/requests/aiohttp to those standard types
so it's a bit more up front investment in writing those classes and laying out all the types
but it's worth it, it pays back many times over in maintainability and testability
and not just your testability. now you can make it a lot easier for people who use your client SDK to write tests, either by providing them testing utilities or at least by exposing these types for them to work with
one of the only problems in this particular setup is that SomethingDomainSpecific could turn out to be some kind of huge ugly union
but you can arrange the types differently to avoid that
Is there a way to test django core.email with mailhog in unit tests?
@pearl cliff What do you think about https://requests-mock.readthedocs.io/en/latest/overview.html ?
Your example kind of handwaves the part where you actually need to interact with httpx
Or at least generate a response that the real httpx would
i've been using httmock, i haven't seriously evaluated alternatives, but it works for me
it's almost entirely boilerplate, getting the method, url, headers, etc. off the HttpRequest object, then wrapping the response in HttpResponse
i had written a lot of that boilerplate at one point, including support for streaming http requests and responses, which turned out to be doable but kind of complicated
it's the kind of thing that could benefit a lot from a carefully designed "glue" library
if i find the code i wrote i'll happily publish it under a free-as-in-freedom license
Well, that is an interesting way to write clients. I had not considered that. Not having a standard for a request object between the various libraries does make it kind of annoying unfortunately.
i agree, but that's pretty much a "write once" thing
i think originally sans-io was developed for "low level" protocols, like parsing HTTP
it has moderate mindshare in the rust world, and it's what httpx uses under the hood (which is why it can support both asyncio and trio so easily)
but doing it at the "higher level" like i am describing is, to my knowledge, very uncommon
i don't know any serious examples of it in the wild, but whenever i've used it at work the productivity and maintainability gains have been significant, once i got the HttpRequest boilerplate out of the way and had some nice reusable primitives
https://sans-io.readthedocs.io/ this is where i originally got the idea
i'd argue that it's also much better than using an IO-like monad, and the haskell version wouldn't be much different conceptually
I appreciate the sentiment but wouldnt thousands of hours also be wasted if you had to write the glue between your http client and the api wrapper every time instead of just using something that works out of the box?
like i said, the glue is write-once use-almost-everywhere
So the theoretical carefully designed glue library is something that can glue any API wrapper to some specific HTTP client? or just a specific API wrapper?
I don't see how the former would be possible without a standard for the request/response objects as Mark mentions
I think that from the perspective of the average Python developer looking to interface with some API, being able to do pip install my-api-wrapper and being ready to go is simply too convenient
In contrast with having to do that, then also choose & install a HTTP client, then glue them together (or use some framework/library to do so)
However perhaps what you propose would also allow you to use the same API wrapper both synchronously and asynchronously? Since the developer would be in charge of choosing how the networking is done & building the requests is cheap
@plush vale to be clear, end-users should be able to do something like this
import httpx
from my_client.io.httpx import MyClient
with httpx.Client() as http_client:
client = MyClient(http_client)
or better yet,
import httpx
from my_client.io.default import MyClient
client = MyClient()
ah, so the API wrapper provides the glue
yes, either it provides a fully-glued-together default "io implementation", or at least the glue to make it easy to roll your own
okay, so ideally it would also provide glue for some mock/testing framework
yeah, and also most of the "glue" is entirely domain-independent
converting an HttpRequest into an httpx.Request, and converting an httpx.Response back into an HttpResponse, has nothing to do with my_client
so the "glue" consists of:
- carefully-designed
HttpRequestandHttpResponsetypes - libraries to serialize/deserialize the above from/to httpx, aiohttp, requests, et alia
it won't be a magic bullet for all cases, but i think it would do a really good job in many cases
I see, thanks for explaining
I'm thinking of how it'd manage the HTTP client dependencies
If you're not going to use requests you don't want to install it with the framework
i did that in the past with pip setuptools extras, pip install my-client[httpx]
right, but don't you run into import errors then, if httpx is not there?
I imagine the lib has to import something from httpx
to tell if httpx is being used
am I making sense? ๐
yep, that's exactly what happens
I guess you can work around it by catching errors from importing the glue module
you can be "nice" to your users and catch/re-raise the ImportError with a detailed error message at the top of my_client.io.httpx
I briefly considered that the glue bit itself could be an optional dependency / extra, i.e. pip install my-client[my-client-httpx]
and my-client-httpx would then bring httpx
and the glue
yep
ah okay I see
E.g. at the top of my_client/io/httpx.py:
try:
import httpx
except ImportError as exc:
raise ImportError('Reinstall my-client with `pip install my-client[httpx]`', name=exc.name, path=exc.path)
and setup.py would have extras_require={'httpx': ['httpx', 'sansio-glue-httpx']}
sorry I forgot in the example the user chooses to import from my_client.it.httpx, so it's on them if that fails
I thought there'd just be one client that would receive an instance of httpx.Client and branch based on that
okay, makes sense
ahh yeah. you could do that too but i wouldnt want to for the reasons you were touching on
๐
Hi, is it the right place to ask some help about selenium ?
Might as well ask it here. I have been working with selenium lately, maybe i can help
Well, I m trying tu use proxies with selenium but the code provided by the documentation seems to not work
I haven't had the need to use proxies so far. But what is the failure and show your code.
what can be the weirdest reason that my django unit test starts failing if I change the name of folder they are present
can anyone help me in making test classes for django more independent, like should I clean db in teardown or what??
Wdym by making tests more independent?
unittest expects tests to be packages
you can either make tests itself a package, or you can put a package inside tests
my-project/
README.md
pyproject.toml
setup.py
src/
my_package/
__init__.py
foo.py
tests/
test_my_package/
__init__.py
test_foo.py
you can do it with pytest too
Can we test a bubble sort function after web scraping a table from a website and sorting the dta using the bubble sort alorithm.!
def sort_bubble (df):
n = len(df['Total Cases']) - 1
s = df['Total Cases']
# Traverse through all array elements
for i in range(n, 0, -1):
for j in range(n, n - i, -1):
if s[j] > s[j - 1]:
df.loc[j], df.loc[j - 1] = df.loc[j - 1], df.loc[j]
return df
Since i am new to unit testing just wanted some help here!
i am also using selenium here!'
@burnt pasture Please don't try to ping @everyone or @here. Your message has been removed. If you believe this was a mistake, please let staff know!
@knotty rover Why would you use bubble sort instead of the built-in sorted function?
or list's sort method
Also, if your question isn't related to unit testing, you should see #โ๏ฝhow-to-get-help and claim a help channel.
good day guys
I'm looking for pylint watch modules like pytest-watch
any recommendation?
Can we do the unit testing for an UI side? like web dev, or it's not necessary?
We can probably, I think with selenium?
ye, though those are generally called/used as integration tests
but yes, that is the primary function selection, tests
is it possible for this to be automated and included in CI/CD pipepline?
yes
but I only did it once and it involved a lot of stupidity which could probably be avoided if I knew what I was doing back then
so is there any reference for the best practice to implement this? in my case i'm using django as a backend and react.js for the front end..
there are probably CI specific guides for this
If you know Javascript, use cypress. Much better experience than selenium
Noted, ill try this one, selenium is kinda limited tho
Can anyone help me understand mocking data for unit testing