#unit-testing
1 messages Β· Page 25 of 1
I want to test the bubble sort function in the code and I am unable to mock the data!
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
its not quite clear why the heck one would mock the data for a sort algorithm, the very test needs to sort actual data
also typically one would implement mutating sort algorithms on top of a Sequence not a class with a number of dictionary entries and data element - i presume df is a data frame bringing in external data?
yeah thinking the same
I wrote a class, and all the class is doing is implements authentication via GitHub. What would be the best approach to test it?
Monkeypatching aiohttp seems like a lot of work, and using dependency injection also seems a bit redundant because all the class is doing is interactive with the outside world. Should I just not write any unit tests for it, and leave it to integration tests?
Situations like this I usually approach as...
- if other tests have dependency on this test, I make dependency injection, if this dependency is slow to speed up other tests, or if I am not 100% sure that it will not break in other tests. Otherwise I could go without injections.
and at the same time I always have left integration test
2) that checks only this thing works properly without injections
Well, I can't really run it without injecting/mocking because it uses secrets from configuration and such. and I don't want to bombard Github with a 1000 requests
now that I think about, mocking what I need in aiohttp isn't that bad
if I can...
if this this makes only one request
that I can wrap in my tests to particular case...
I use vcr
vcr?
ah
then uses saved file for all other repeated invokations
it is requiring literally only one function to use
import vcr
with vcr.use_cassette("unique_file_path_for_this_request.yaml"):
your_request()
I still have the issue of requiring real github credentials. If I understand what unit tests are for, they should just test the logic behind my code, right?
at least import requests library is caught well
there are three types of tests...
unit tests yeah, should be checking only your code logic
integration tests check your interaction with dependency... which can be github, filesystem, database, or just library out of your control
technically... things within your control database/filesystem/your own other microservices are still part of unit tests in my opinion, at least if your keep those dependencies deployed with devops tools, which means this infrastructure remains part of your code
real integration tests check dependencies which are totally out of your control, github, third party applications
there is also third test category, which goes for end to end testing
btw, if the test requires credentials
you just move this info out of your code... to environment variables, which can be managed easily with .env file, which is in your .gitignore, i keep .env.dev, .env.test and e.t.c. files for different configurations
github/gitlab piplines can be filled with stored SECRETS if necessary
situation becomes a bit more troublesome, if credentials look like a big file though
Yeah, I understand that
I decided to give up and just not write any unit tests for this π
https://www.youtube.com/watch?v=GKSRyLdjsPA
lyrics:
Don't give up, I won't give up
Don't give up, no no no
Is anyone familiar with PyTest? I'm trying to develop a habit of building more unit tests into my projects, and there's a class that I have created with a single method. I want to write unit tests for them, but I just need a bit of help thinking about what would be something that should be tested.
I'm thinking that I could share the code, and then we can discuss what would be good to test, then I can figure out the implementation in PyTest on my own
@elder relic please write out your questions ^^
Sure. My question is, from this code that I have below, what are some things that I can think about when trying to write out my unit tests? I don't really understand what it is that I am testing for, so hopefully that's enough to get started:
from pandas import read_csv
class StackOverflowDataFrame(pd.DataFrame):
@property
def _constructor(self):
return StackOverflowDataFrame
def find_multi_response_columns(self, delimiter):
survey_data = self.copy()
columns = survey_data.columns
multiple_response_columns = []
for column in columns:
for response in survey_data[column]:
if type(response) is str:
if f"{delimiter}" in response:
multiple_response_columns.append(column)
break
return multiple_response_columns
path = r"C:\Users\djgra\Desktop\developer_survey_2020\survey_results_public_2020_sqlready.csv"
df = StackOverflowDataFrame(read_csv(path))
So the class isn't super complicated. I am subclassing pd.DataFrame and then my methods do some particular processing. So I want to try and begin to get myself thinking about what good testing looks like, because I have never written tests before, I normally just reason about my code.
my first suggestion would be to not use a own class, just have a helper function
then in a unitest, yo ucan just invoke that helper
When you say "not use a own class", do you mean in the context of trying to test, or just generally?
Like for the purposes of testing, write things in functions?
#medical history
print("Get to know ur patient's medical status with this tool")
patient = "Ur patient's"
stool_colour = input(f"Question 1 : What is the colour of {patient} stool (poop)= ")
Urine_colour = input(f"Question 2 : What is The colour of {patient} urine: ")
Blood_glucose = input(f"Question 3 : What is {patient} blood glucose level? = ")
if stool_colour == "dark yellow" and Urine_colour == "pale yellow" and int(Blood_glucose) <= 120 and int(Blood_glucose) >= 80 :
print("patient is normal. Have a good day!")
else:
print("Your patient isnt well.")
I am new to python
so any mistake please inform
I just want to make sure I am on the same page as you.
it depends, the code of the example is something local to your domain - my personal preference is to put helpers that take data out of something more general just into a function
as far as i can tell, your helper is for finding columns where elements have particular properties, so its not eeven part of the direct problem domain
Yeah, fair enough. I wrote everything out as functions first, but I have to do a lot of other work to get this large csv table into a lot of different tables that can then be copied into postgres. So the purpose of the class is just to keep the workflow phases organized.
In any case, let's suppose that I do just have the find_multi_response_columns method written as a function. In trying to test that particular function, what would you try to implement in your unit tests?
Because I think that with unit tests, we want to make sure the individual functions are working as we expect them to, right?
passing it dataframes with known structure and asserting the results
Let me see if I can expand on that a bit further. So my helper function extracts all of the columns that are classified as "multiple_response_columns". For the sake of example, let's suppose I know for sure that there are 7 columns that satisfy that condition, and maybe I know this because I have looked at the original data or something.
So in this instance, I would pass the helper function a dataframe and then assert that the number of columns is 7.
I appreciate the patience by the way
yep
i would also recommend reading a bit into dataframes string utilities as it would help to use the tools there
as for the question about testing this logic in general: figure out some "invariants" that must always be true for any input
leaving aside possible refactorings, your tests could look like this:
- randomly generate a dataset full that meets certain properties
- run your code on it
- assert that the output is what you expect, given the properties of the input
for example, you can randomly choose from the delimiters ,, ;, |, and maybe other weird ones. then you can use the test assertion that the number of columns is exactly what you expect.
generate a table of column names and data types, generate fake data with those types, then assert that the resulting dataframe has those same column names
in python we have the excellent Hypothesis library to help write these kinds of tests https://hypothesis.readthedocs.io/en/latest/ (specifically, it helps generate the fake data and gives you some debugging and introspection tools)
not related to testing: write isinstance(response, str) instead of type(response) is str. there are good technical reasons to prefer the former.
i agree though, i really don't think this should be a subclass of a dataframe
is this really a "new type" of object? or is it just a helper function?
and what's with the _constructor property?
or is that a pandas internal thing that you're expected to override when subclassing?
It's a pandas internal thing. So there's two reasons why I chose to write this as a class.
The first is that I wanted to get some experience working with classes. The second is that my workflow down the road ends up getting kind of complicated because of the procedures I need to perform on the data.
So my thinking was that I could segment my workflow into different phases via classes and try to make the code more modular as opposed to just having a ton of different functions.
i see no reason not to have standalone functions like this:
def is_multiple_response_value(delimiter: str, value: object) -> bool:
return isinstance(value, str) and delimiter in value
def is_multiple_response_column(delimiter: str, data: pd.Series) -> bool:
return any(
is_multiple_response_value(delimiter, value) for value in data
)
def find_multiple_response_columns(
delimiter: str, data: pd.DataFrame
) -> typing.Sequence[str]:
return [
colname
for colname, series
in data.items()
if is_multiple_response_column(delimiter, series)
]
Hmm, yeah I mean I don't either haha
i would offer that subclassing will make your life harder, not easier
if you want to practice with classes, implementing a scikit-learn estimator or transformer is a great exercise
I appreciate the feedback. Maybe I will just work on making the helper functions I already have written a lot better.
If two of you are saying the same thing, and I presume you guys are well versed in the language, then i'll take your advice.
One thing though - why do you explicitly have the datatypes in the functions? Is it just for clarity?
(btw, this is a very productive conversation, so thank you)
keep in mind that the main benefits of classes are:
- encapsulating mutable state - database connections, state machines, arrays of numbers, etc.
- keeping "records" organized - e.g. a
Personwith anage,name, etc. - implementing interfaces and single dispatch
defining a new class like DataFrame makes sense because there is a lot of internal state being encapsulated. if your StackOverflowDataFrame does some kind of internal magic that automatically dispatches to this or that helper function when a "multiple response column" is encountered, but that otherwise acts the same as a DataFrame then maybe yes you want to subclass DataFrame. this is because DataFrame (informally) adheres to a certain interface, and you might want your StackOverflowDataFrame to adhere to the same interface.
but this is not something i'd use or encourage for data analysis workflows, because it makes it harder to see what's going on. in an "application", it might make sense.
these are type annotations. they can be checked by a type checker such as mypy (http://mypy-lang.org/), which has a lot of benefits
I'll take a look into them then, perhaps I can try to integrate them more into my work.
Because right now, as you can tell, I do not.
i use them everywhere in "production" code. however they can be too verbose to use in "interactive" or exploratory work
that's one disadvantage of python compared to other languages that have a static type system built in
Yeah, it is as if you are trying to bring static typing into Python, which for me is something I wouldn't have thought much of. I know Java is like that, and same with Go, I think JS as well but I am not sure.
it's not always possible (there are a lot of limitations compared to a true statically typed language), but if you can write your code to pass mypy --strict then you can rest assured that you have prevented at least one entire category of errors
Solid. Well, I will take this conversation, sit on it a bit, and rewrite some of the code I have and try to implement some tests. If I have troubles, i'll come back in a few days and reassess.
Appreciate all the help, and your patience.
one last thing that's more specifically about testing: helper functions tend to be easier to test than classes with instance methods, in my experience
Hello everyone, I'm new here so I'm sorry if I'm in the wrong channel.
I've a question, what's the pythonic way to check the input of a method ?
Is there a way to execute a teardown after all other tests have run? Currently I have created a setUpClass and used tearDown instead of tearDownClass, as I understand the class-methods will run before all tests, which is fine for the setup, but not the tearDown. However, I'm not sure if tearDown run after all tests are done or after each tests?
To illustrate if my testfile has the following setup:
class TestClass(TestCase):
@classmethod
def setUpClass(self):
def tearDown(self):
def test_1(self):
def test_2(self):
my problem is I have setup some sql queries in the setUpClass, and say I use a particular query in test_2, but in my tearDown i delete it.
Possibly you want to run setup before each test?
Then teardown each test?
To keep tests seperate
you can also use tearDownClass https://docs.python.org/3/library/unittest.html#unittest.TestCase.tearDownClass
I am using pytest and I don't know what to do when tested function raises an exception.
I can mark test as @pytest.mark.xfail(raises=...) or use pytest.raises(...)
with pytest.raises(...):
...
Is there a reason when I should mark as xfail over using pytest.raises? Or maybe should I prefer pytest.raises?
@low pagoda pytest.raises specifically asserts that some code raises an exception https://docs.pytest.org/en/latest/reference/reference.html#pytest.raises, while pytest.mark.xfail marks that a test is expected to fail https://docs.pytest.org/en/latest/reference/reference.html#pytest-mark-xfail-ref. i would prefer the former for testing code, and the latter for managing the test suite itself, e.g. some part of the test harness is unavailable and you want to just skip the test in that situation.
No that's what I'm trying to avoid. Cause I set everything up in setUpClass
the problem is this
currently what i've shown mean the calls are as such:
setUpClass called
test_1 called
tearDown called
test_2 called
tearDown called
If i have a query in setUpClass that is used in test_2
it won't be tested before it's deleted
tearDown is on function afterall
@proper wind i think you just need tearDownClass instead of tearDown
@silk ridge :x: Your eval job has completed with return code 1.
001 | How old are you?: Traceback (most recent call last):
002 | File "<string>", line 18, in <module>
003 | File "<string>", line 3, in __init__
004 | EOFError: EOF when reading a line
Etf
hi how you guys make your selenium undectectable.
on another server where discussion of things that probably break a website's ToS are not prohibited by the rules π
when using !pypi coverage
how do i set what threshhold of % covered when to fail
!pypi coverage
ah nevermind found it of course use the --fail-under=PCT
how "DRY" should my tests be? I feel like if I'm extracting literals away from the test, they become hard to read
usually as much as makes sense, usually literals and their constant variables are very similar in naming so shouldn't be that hard to read if that is what you mean
HELLO_WORLD_MSG="hello world!"
my tests tend to be "wetter" than the code itself
yeah, though still better to be DRY but definitely not nearly as strict as the code itself
For context, I'm writing tests for a web API, and it seems to me that they are really long and drawn out ```py
@pytest.mark.asyncio
async def test_authenticated_user_can_delete_their_own_post():
auth_provider = FakeAuthProvider()
content = PostContent(
"The title",
{"foo", "bar", "baz"},
[Header("a header"), Paragraph("some text")]
)
post = Post(42, User("Bob", "Bob B.", "bob.png"), content)
post_repo = FakePostRepo({
42: post
})
endpoint = PostsEndpoint(post_repo, auth_provider)
client = TestClient(endpoint.app())
token = await auth_provider.log_in(AuthUser("Bob"))
headers = {"Token": token.content}
resp = client.delete("/42", headers=headers)
assert resp.status_code == 200
assert await post_repo.all_posts() == []
```, and it's getting progressively worse when I need to include more data. So I'm wondering whether there's a good way to create a library of fake data (like Posts here) to reuse it, without forcing the person reading the test to constantly jump back and forth
PostsEndpoint is the actual thing I'm testing, it's an ASGI app that represents a "branch" of my application
TestClient comes from Starlette
ahh so you want to know how/if you should have separate functions to create a mock content, post, post_repo, etc. object rather than clutter it here
I was thinking of creating fixtures with several data sets
but the thing I'm worried about is that you'll need to go back and forth between the definition of the dataset and the actual test
yeah, that is kind of preference, in this case I don't think needing to know all of the details of for example the post content is necessary to the test but up to you here
I think I'd prefer just copypasting some common bits, for the benefit of tests being painfully obvious
well, unless something is repeating in all tests
yeah, that is perfectly fine
readability/understandabililty is definitely important in code
also... I can imagine the pain I would need to go through if I also needed to wrap the function in monkeypatching decorators
and patch asyncpg and Github's OAuth server here
no pain no gain π
your IDE gives you warnings for repeated code?
what's an example
yeah this is just the nature of testing, ignore your IDE
but if you want, you can abstract this to a separate list of moves and expected generated moves
class TestGeneratedMoves(TestCase):
self.test_data = {
'black king possible move into pawn check': (
[((1, 1), King("BLACK")), ((1, 2), Pawn("WHITE"))],
(1, 1),
{(0, 0), (1, 0), (2, 0), (0, 2), (1, 2), (2, 2)},
),
'white king possible move into pawn check': (
[((1, 1), King("WHITE")), ((1, 0), Pawn("BLACK"))],
(1, 1),
{(0, 0), (1, 0), (2, 0), (0, 2), (1, 2), (2, 2)},
),
}
def test_generated_moves(self):
for label, (piece_positions, start_coordinates, expected_moveset) in self.test_data.items():
with self.subTest(label):
board = Board(_length=3)
for coordinates, piece in piece_positions:
board.put_piece(coordinates, piece)
actual_moveset = generate_move(board=board, from_coord=start_coordinates)
self.assertSetEqual(actual_moveset, expected_moveset)
of course you might prefer using some kind of GeneratedMoveTestData dataclass instead of a tuple, but it's the same idea
Hey, i am trying to make a tester for my API, just a simple one that calls the URL and query
i keep getting stuff which involves initialization of .db (which i assume is database), does any tester need this?
and i dont have a database really, i am using someone else's
@proper wind What framework are you using? Can you show the test code and the error?
alright, i will in a sec
i was out running some errands so i can now
im using flask API
i want to test queries and calls for my API, but sofar all i got from unit testing online is basic funcion testing using py tester
Potentially
import responses
import requests
@responses.activate
def test_simple():
responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
json={'error': 'not found'}, status=404)
resp = requests.get('http://twitter.com/api/1/foobar')
assert resp.json() == {"error": "not found"}
assert len(responses.calls) == 1
assert responses.calls[0].request.url == 'http://twitter.com/api/1/foobar'
assert responses.calls[0].response.text == '{"error": "not found"}
thanks
Anyone have experiiience adding a javascript testiinig framework (Like jest) to a django application?
Hey can someone send a ddos attack to this ip? I'm creating a VPN service, and I want it to stand straight attacks. This is just a test ip it doesn't belong to anyone, it's sole purpose is to act as a test, I'd like a hard attack, preferably for a day. The Ip is 192.168.8.243
that IP is on your local home network, it won't be accessible from the outside anyway
My apologies I didn't mean vpn, I meant cdns
It's not meant to hide my ip, it's meant to withstand attacks like cloudflare.
192.168.8.243 is reserved for private IP addresses, such as on your local home network
if i run ping 192.168.8.243 i get a request timeout, because there is nothing on my local network with the IP address 192.168.8.243
ARIN specifically designates the 192.168.0.0/16 range (192.168.0.0 through 192.168.255.255) for private use, and those addresses will generally not be routable from the internet
I see. So you wouldn't be able to send packets.
indeed
That ruins the test:/
you will need to expose it through your router. then if you set up a remote server to dos yourself, you'll probably just end up dosing your home router.
anyone available to help me with docker setup and understanding?
I am trying to setup jest.js to test the frontend of a django app
I see thank you for the info. I'd like to try and change my ip for tests. I'm assuming though I'd ddos my router that isn't for testing as well?
doesn't seem like it's what you want to test
Anybody can help me
How would I handle exceptions from unit testing?
raise self.failureException```
If the exception is intentional just catch the exception and set a variable (example βraisedβ) and assert raised at the end of the test
If ypu use pytest, it has a context manager named pytest.raises
Thanks guys
Is pytest what everyone is using these days?
I find it much more intuitive than unittest so for me yeah
Thanks for this! I rather save time
I am writing integration tests that have multiple pytest fixtures that use the same limited resources. How do I adjust the scoping such that these fixtures can all be run in the same module/session without the resources being depleted?
I want to control the reservation of these resources at the session level though but if all the fixtures have a session scope they end up reserving the resource for the entire session and tests end up not being able to run
Also if I run the fixtures at the class scope the tests end up taking way too long because of the time it takes to reverse and configure the resources
Hello all
I am starting to write unit tests for my project. I would like to have unit tests to run without any external system including database. So one way to mock the database calls itself. So having few questions related to it.
- Is it good idea to mock the db calls or should spawn the db system at the time of tests?
- If mocking is fine, then are there any patterns to mock such calls? If anyone can suggest any opensource project where I can look for the similar tests writing.
database is a thing fully under your control, better spwaning the db system at the time of tests.
in fact, django framework does it automatically for you. During tests it makes empty migrated database for each test.
Possibly it does testing framework perhaps, not the Django? not sure which part of my app does that.
Additional advice: if you are going to use postgresql in production, it would be better to run your tests in postgresql (not in sqlite) (as a last resort in sqlite will do too, at least it is better than mocking).
can anyone help me with python web scrapy unittesting
im kinda stuck in testing the parse part and dont know how to start or do
I want to learn testing .... it appears i could use pytest, unittest, nose
is there a preference amongst these ?
Don't go with nose, its declining rapidly. Unittest is unintuitive imo. Pytest is the way to go.
Thank you @fresh blade
nose has been unmaintained for more than five years
how did you decide that nose was still viable?
what, their repo is embarrassing. The last commit was to update changelog to add a new unreleased feature. What happened??
furthermore, 10 years+ of development and only 1,006 commits?!
Projects come to an end sometimes. Read the first sentence on the home page: https://nose.readthedocs.io/en/latest/
I've been working on something for 2 months and have already 300+ commits
true. Surprised that coverage.py still documents how to use nose.
and that sentence was added six years ago: https://github.com/nose-devs/nose/commit/0f40fa995384afad77e191636c89eb7d5b8870ca
Yeah, maybe i'll remove that soon
or update it to nose2 π
seems to be maintained
nose references seem to be all over the python ecosystem docs
What does --basetemp="{envtmpdir}" exactly do in the tox.ini example here: https://tox.readthedocs.io/en/latest/example/pytest.html
I don't understand what "change dir before test and use per-virtualenv tempdir" means 
Also, is there a way to run tox from code rather than command line so i can hook into vsc debugger?
oh, it's literally this
```py
import tox
tox.cmdline()
dunno, maybe try see what it uses the temp dir for
the example is slightly incorrect and should use commands = pytest --basetemp="{envtmpdir}/pytest" {posargs}
when giving pytest a basetmp then it will not make a per testrun tmpdir in tmp, but prune the given directory and use it instead,
however no harm is done as tox will clean the env tmpdir right before a testrun anyway
hi, anyone works on postman here for testing?
I have a doubt, how can I set default query parameters to a collection which applies to all the requests in that collection?
I don't think so, but you can at least put the data into a variable for that collection
Is there a way to have pytest show the number of tests per file rather than just dots? like the (9) here that I've inserted ```
tests\run_many\languages_json\test_languages_json.py ......... (9)
I don't want to use verbose mode since that's too verbose π
I am not sure, I understand you, but maybe use variables?
duh, use verbose mode and write a C program to parse it. this is unix after all, and C is a high level language.
How sensible / silly is it to have different tests run on different systems? I have some tooling which uses google things, which aren't tested because there's application credentials and stuff required to run them (and I'd rather not test googles stuff but just trust it works - these are wrappers around things like bigquery / translation and whatever).
The other day someone refactored something, and broke some of the tooling, so I was considering having a subset of the tests run locally (where the application keys are set), and the rest run on CI and local π€
i'm not sure if this is a "done thing" or not though
both pytest and unittest have features that let you conditionally skip tests
it's not the worst thing ever, but it might lead to tests that you have less confidence in
List of SeleniumBase features completed/updated over the past year: https://github.com/seleniumbase/SeleniumBase
- Dashboard
- Dialog Boxes
- Product Tours
- Chart Maker
- Presenter
- Locales
- Visual Testing
- Traffic Generator
- Universal Translator
- ShadowDOM Piercer
- SOCKS 4/5 Proxy Setter
- ChromeDriver Auto-Upgrader
Hi unit test peoples. How would I go about unit testing a script that makes REST API calls using requests? Would I create a mock response and test that?
I've used https://requests-mock.readthedocs.io/en/latest/ and it has worked out nicely
yes, you will need to create some fake data to "respond" to your requests
it depends on which REST API you are mocking.
if it is third party integration, use mocking ways
if it is within your own code base, better just making regular request
:incoming_envelope: :ok_hand: applied mute to @normal meadow until <t:1630041911:f> (9 minutes and 58 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
i'm working on a pytest fixture which ensures that a test does not produce any garbage or explicitly run gc, but having some trouble testing that it works as intended; when i use a strict xfail marker on a test that produces garbage and correctly causes an error, it still detects xpass and fails, there doesn't seem to be any "xerror" marker which is what i would need. maybe producing an error from the fixture isn't what i should be doing?
import gc
import pytest
@pytest.fixture
def nogarbage():
did_gc = [False]
def fail_gc(phase, info):
did_gc[0] = True
was_enabled = gc.isenabled()
gc.disable()
gc.freeze()
try:
gc.callbacks.append(fail_gc)
yield
gc.callbacks.remove(fail_gc)
assert not did_gc[0], "Garbage collected during test"
for gen in range(3):
assert gc.collect(gen) == 0, f"Garbage collected after test (gen {gen})"
finally:
gc.unfreeze()
if was_enabled:
gc.enable()
@pytest.mark.xfail(strict=True)
def test_circular(nogarbage):
l1 = []
l2 = [l1]
l1.append(l2)
this looks like the answer https://stackoverflow.com/a/56635224
you can mock both, request and response, if necessary
Thanks everyone. Is there any examples of that out there?
I would think on the design of the tests. Test, if the view receives the request correctly - mock request. Test, if the data is serialised correctly - mock the data. Test if it returns the correct response - mock response.
pytest.raises? or pytest.mark.xfail(raises=IdkError)?
i'm interested in this tooling for testing the test fixtures
i never had a good solution for that
pytester is the solution, thing is raises and xfail are made to deal with test failures, not fixture errors
the pytest plugin cookiecutter actually sets this up for you
def test_nogarbage_fixture(testdir):
testdir.makepyfile("""
import gc
def test_fail(nogarbage):
assert False
def test_pass(nogarbage):
pass
def test_circular(nogarbage):
l1 = []
l2 = [l1]
l1.append(l2)
def test_collect(nogarbage):
gc.collect()
""")
result = testdir.runpytest(
'-v'
)
result.stdout.fnmatch_lines([
'*::test_fail FAIL*',
'*::test_pass PASS*',
'*::test_circular ERROR*',
'*::test_collect ERROR*',
])
assert result.ret != 0
where conftest.py has
pytest_plugins = 'pytester'
neat
pytest and unittest find the tests by filename, right? What are the most common naming conventions? Anything with test in it?
Pytest finds according to pytest.ini config in your project.
Yes, usually test_*.py, tests.py files are searched. And functions always start as test_ too
Cool, I'm doing a mixed Python/C++ project and just want to make sure I'm using consistent naming schemes. In C++ some people prefer some_file.test.cpp for example.
Python convention for test searching can be adjusted
Check if u can adjust c++
If not, then better to follow c++ convention
yeah, all the C++ ones are just listed explicitly in a config file, they could be called anything in principle.
Well. U can follow convention of both languages then
It does not look like conflicting
It will make less confused python devs, if others will participate
less confusion is a plus
Does ubuntu have a disk wipeing program buiit in
yeah, it is called Disks
Hi
I have done functionnal tests on a flask full api using pytest
Firstly I want to know if the testing must be done when the app is running or not (I think so)
Because I have an issue when testing a given route that is calling another api (inside my own app)
The tests in the detailed log said that it is not reachable (the other api nested)
When I run the app the tests works surely
How to fix this issue
plz
Flask provides special testing api client, go with it to make pseudo external requests
with the app closed?
Thxx
I want to do a prebuild tests
so the app should be closed, no? @maiden pawn
Official docs should be providing example how to use it
I didn't find any thing π¦
ok thxx I will see @maiden pawn
@maiden pawn plz can you send me the name of the section in detail or a screen or a part of the paragraph
I didn't find it
Please @all any help
does unittest support async tests?
I used async plugin support for pytest, it worked smoothly
Yes it does out of the box since 3.8 or 3.7, something around there
You have to inherit from a special testcase subclass for async tests
cool.
https://docs.python.org/3/library/unittest.html
yeah, official documentation has examples, 3.8 it is
# New in version 3.8.
from unittest import IsolatedAsyncioTestCase
# the next code
Thanks for finding that I couldn't remember the name and I'm on mobile
Hi, How to design a test that can roll one parameter out?
I've designed a model that some of the column are nullable and some are not.
Is there any source that I can follow for this situation?
Thanks!
For example: suppose duration is nullable and others are not, then I might need two test cases to confirm that either missing plan_id or missing available_before will raise the error.
The dumb way I've thought of is create two Plans for the test, but any smart way to deal with it?
def test_add_param_deficient_plan(self):
try:
p = Plans(
plan_id = "standard-month-1",
available_before = dt.strptime("2021-08-20", "%Y-%m-%d"),
duration = 1
)
db.session.add(p)
db.session.commit()
except:
db.session.rollback()
self.assertRaises(exc.IntegrityError)
why couldn't they just call it AsyncTestCase
lol thats too verbose
TIL that exists, and yeah what a ridiculous name
i assume it's "isolated" because it uses its own separate event loop
i've been using my own decorator that wraps test cases in asyncio.run
time to switch
ye pytest-asyncio takes the same approach of running each test in a new event loop, which makes sense (by default, you can redefine the event_loop fixture)
to allow testing using different loop implementations, and to ensure resources dont leak between tests
though I was dealing with the problem recently that as a result you cannot share async resources like db connections between tests because then they get bound to the wrong loop
maybe you shouldn't do that anyway
but there's also the consequence that you cannot have an async fixture scoped above function (eg to run migrations in session scope)
i ended up solving it by just having a sync fixture and doing asyncio.run inside, couldnt think of a better approach, im a noob π
event loop scoping is annoying
the loop "closing" and not being restartable is annoying too, not sure if that's a technical limitation or just a design oversight
Hey people
How do you deal with large files in github?
Like i need to have a large bianary (linux kernel) in my github CI
The CI will run some tests using that binary
but since the kernel is like >500Mb , git wont work
git LFS may work
but is it the best solution?
has anyone come across this problem?
def create_xyz_table(self, table_name: str, source_table_name: str) -> None:
logger.info(f"[+] Creating table [{table_name}]")
self.mysql_client.run_mysql_query(f"CREATE TABLE `{table_name}` LIKE `{source_table_name}`")
logger.info(f"Table [{table_name}] created")
Hi, I am writing unit tests for this method.
I already have a unit test that asserts that run_mysql_query has been called.
I would maybe like to have once that verifies the query that is passed to run_mysql_query. My only worry is that there is then code duplication... 1 string will be in my unit test, and another string will be in the function.
Yes, I am facing that problem too, where it isn't feasible to generate the test data so it must be stored. The problem with checking in a binary on git is that anyone who clones it will clone this large binary too, even if they may not be intending to run tests. It's even worse if you plan on updating the binary since that will end up bloating the size of git's history.
You could host the binary on a server and have CI download it. Downside is that the server could go down in the future and there won't be a way for people to get this test data.
One idea given to me was to have some smoke tests that don't rely on large binaries, and then have the CI run the full tests by downloading the binary from another server.
@kind meadow I see.
What i;m thinking is to build the binary in the CI intially and then cache it
So it stays in the CI cache.
I keep it in separate repository for now %
special repository "for big files"
github has a feature called LFS
I'm planning to use that if I can;t come up with any better indeas
oh, that's a neat choice
Thanks
Actually im kinda new so i thought people might have better solution to this
well, for most of heavy stuff
I just have download on a fly instructions
building dockerfile with downloading stuff from where it is
But for it each CI run will take ages
First download the linux kernel, then build it
erm. That would be fine as long as you have unlimited CI ;b
plus you could use its caching/artifacts (or how it is called there)
lol
i'm in college
Yeah thats another solution
that after running it once we cache it, so nect time CI doesnt take time
in theory
we could have all those dependencies
being available for download
from our running server
while having them stored in separate repository again
this will make sure that we will be able having those dependencies
self raised and downloaded from our own server, being sure that they will not dissapear
but that's a bit too crazy solution
for small things probably not needed
indeed its a crazy one, for a two man project
maybe bigtime projects do this
btw, Thanks for ideas
@open venture LFS is a fine option. another option is to use DVC (which is mostly used for data science but could definitely be used here) and then store the binary in a separate location that you can pull from in your CI
yet another option is to just push the binary to some file store you control, like a basic ftp server on a cheap vps instance
I see thanks @pearl cliff
Hi, can someone help me with my project idea is to test a program i tried to make ( the program is to put in ingredients we have and it shows the available recipe for us), it just an idea not to fully make the program.
start with https://www.manning.com/books/unit-testing this book ;b
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.
it is great to learn testing philosophy
ohh
Can anyone here help walk me through the Mock() object and the patch() decorator?
I read a few articles on it and a few things are still unclear
requests = Mock()
def get_holidays():
r = requests.get('http://localhost/api/holidays')
if r.status_code == 200:
return r.json()
return None
class TestCalendar(unittest.TestCase):
def test_get_holidays_timeout(self):
# Test a connection timeout
requests.get.side_effect = Timeout
with self.assertRaises(Timeout):
get_holidays()
if __name__ == '__main__':
unittest.main()
For example in this snippet, how do I know get_holidays() is handling the Timeout exception?
Timeout gets raised first, then why would I call get_holidays() afterwards?
Shouldn't the Timeout happen inside the get_holidays()?
I think the with self.assertRaises(Timeout): begins a context manager that is setup to cach the exception specified for get_holidays. Then get_holidays is run. If there is an exception it will be returned to the self.assertRaises call. You can also give the return object a name and inspect it after: with self.assertRaises(SomeException) as cm:
I don't know why requests is being set to Mock there though. Typically you would use a decorator over the test to patch the actual requests library and then set the mocked requests to have the side_effect.
import unittest
from unittest.mock import Mock, patch
import requests
from requests.exceptions import Timeout
def get_holidays():
r = requests.get("http://localhost/api/holidays")
if r.status_code == 200:
return r.json()
return None
class TestCalendar(unittest.TestCase):
@patch("requests.get")
def test_get_holidays_timeout(self, mocked_requests_get):
# Test a connection timeout
mocked_requests_get.side_effect = Timeout
with self.assertRaises(Timeout) as exc:
get_holidays()
self.assertEqual(type(exc.exception), Timeout)
mocked_requests_get.assert_called_once_with(
"http://localhost/api/holidays"
)
if __name__ == "__main__":
unittest.main()
Hey people, how to add this checks box to a github PR using github actions?
Like is adding on: [push, pull_request] this to the .yml is enought?
I think you need to set branch protection in the repo settings
this explains it
you're interested in point 7
but the others may be interesting to you too
Cool thanks! In this example, what's the relationship between the patch decorator and the mocked_requests_get argument? I see that was added, but what is being passed? There's a call to the unittest.main() function and that's it. I don't see any input to test_get_holidays_timeout, so wondering what's going into it
The patch decorator is wrapping the function. It's patching the requests.get and passing in the mock of that as an argument to the function for you to use. You can add multiple ones on top of each other as well and they would get added in as more arguments. It gets evaluated bottom up.
@patch.object(SomeClass, 'class_method')
@patch.object(SomeClass, 'static_method')
def test(mock1, mock2):
^ That's from the docs. mock1 would be static_method mock and mock2 is class_method mock. @arctic oak
Very helpful, thanks so much!
Thanks I got it working.
:incoming_envelope: :ok_hand: applied mute to @peak basin until <t:1631026729:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
guys need help in testing Django signals
I have implemented the user login activity
so when the user logs in It fires a signal 'user_logged_in' which creates an entry in a table
I need help in testing this
@patch("datetime.datetime")
@pytest.mark.parametrize(
"input, expectation",
[
(
TestDate(2020, 5),
does_not_raise(),
),
],
)
def test_months_to_archive_year_input_valid(mock_datetime, input, expectation, app_manager):
mock_datetime.utcnow.return_value.year = 2021
with expectation:
result = list(app_manager.get_months_to_archive(input.month, input.year))
assert len(result) == 5
app_manager.py
...
while start_date <= formatted_current:
if start_date.month == current.month and start_date.year == current.year:
break
yield start_date
start_date = start_date + monthdelta(1)
My unit test is mocking datetime.datetime, and this causes problems when the unit test reaches the portion of code that is comparing datetime objects with "<=" because: TypeError: '<=' not supported between instances of 'MagicMock' and 'MagicMock'
Anyone knows how to fix this?
@deft bronze I like freezegun for faking time-based code.
Hi, I have a function that takes three arguments like this:
def func(a, b, c):
return a + b + c
or whatever have you.
I also have a separate tests folder where I would like to test the func.
- is
@python.fixturea good option for this?
I have been trying with this approach and added the decorator to thefuncdefinition in the "code" file, while wanting to test it in another. What is returned to me isfixture 'a' not found. What am I doing wrong? π
what about something like this?
mock_datetime.utcnow.return_value = datetime(2021, 1, 1, 0, 0, 0)
and/or using Hypothesis to generate random dates that meet the constraint
(note: hypothesis apparently doesn't play well with @patch as a decorator)
The
unittest.mock.patch()decorator works with@given, but we recommend using it as a context manager within the decorated test to ensure that the mock is per-test-case and avoid poor interactions with Pytest fixtures.
https://hypothesis.readthedocs.io/en/latest/supported.html#testing-frameworks
i wonder if patch('datetime.datetime.utcnow') works? probably not
from contextlib import nullcontext
from datetime import datetime
import pytest
import app_manager
@pytest.mark.parametrize(
('input_then', 'input_now', 'expected_len'),
[
(datetime(2020, 5), datetime(2021, 1), 5),
],
)
def test_months_to_archive_year_input_valid(input_then, input_now, expected_len, app_manager):
with patch('datetime.datetime') as mock_datetime:
mock_datetime.utcnow.return_value = input_now
result = list(app_manager.get_months_to_archive(input.month, input.year))
assert len(result) == expected_len
@pytest.mark.parametrize(
('input_then', 'input_now', 'expected_err'),
[
(datetime(2020, 5), datetime(1983, 7), (app_manager.SomeException,)),
],
)
def test_months_to_archive_year_input_invalid(input_then, input_now, expected_err, app_manager):
with patch('datetime.datetime') as mock_datetime:
mock_datetime.utcnow.return_value = input_now
with pytest.raises(*expected_err):
list(app_manager.get_months_to_archive(input.month, input.year))
a "fixture" is a function that generates data to be used in a test. if you use @pytest.fixture on a function called thing, then all test functions with a thing parameter will be called with thing=thing(), more or less.
Ah - gotcha! so it's usually on the testing side as a "fixture" (see what I did there? π )for tests to reuse the same data for multiple tests?
@fresh blaze if you want to test that function, you can use pytest.parametrize (example directly above) https://docs.pytest.org/en/6.2.x/parametrize.html#pytest-mark-parametrize, or you can use something like hypothesis to generate random inputs for you https://hypothesis.readthedocs.io/en/latest/quickstart.html
precisely. either data, or some resource like a database connection
@pearl cliff So I would never want to use this decorator anywhere outside the tests file, like I wouldn't want to use it on the "code" side? Or if a resource is defined in code, I would use it there? Like with your example about the db connection, if creds are set up on the "code" side I could potentially use it as a fixture for the tests on the "testing" side?
I read this and I'm not sure I am making sense π
you wouldn't use it on "real code", but you could write a fixture that uses real code in order to acquire the resource
import pytest
from my_very_serious_app import get_database_from_env
@pytest.fixture
def database_connection():
return get_database_from_env
def test_something(database_connection):
...
Perfect - thanks
pytest has a ridiculous number of features btw
i recommend reading that fixtures doc page in small pieces
Yeah I started reading this...and then I stopped
I have one more question on good practice
Let's say I have a .csv file as a resource, where I have a bunch of tweets. It's usually read in by "code" and then processed to fit a particular task, say NLP. If I wanted to test the cleaning function, would I create test strings using some custom-prepared ones as a fixture? or would I be trying to use the initially loaded file as a resource in any fashion?
you could do either or both
do whatever you need to do in order to test that the function "works", where "works" means something like "produces the expected outputs on a controlled list of inputs" or "maintains certain invariant properties on randomized inputs"
right - much appreciated - thanks!
hypothesis helps for the randomization
+1, nowadays i even use hypothesis to generate entire databases worth of data, write the data to the database, and then make assertions about queries against that data
although i really should start looking into ways to control the number of test examples that get generated, i'm concerned i might destroy the ssd on my work computer if i do that too much...
thats an interesting idea π³
i found myself working on a project where extensive testing is crucial and generating the data has been a bit of a pain point
but since i'm still kinda lost in the domain i scheduled a meet with someone senior in the area so hopefully they'll set me on the right path π
it seems to me that proper testing is the hardest problem i keep encountering
for the past couple of days i've been working on solving the problem of paginating huge amounts of data and providing it to the frontend on-demand, but the data is very alive and volatile
and keeps changing in basically real time
the solution itself aside, i don't really have a good idea of how to approach testing this
i'll not only need to generate a lot of data, but i'll have to be changing it as the test is running and somehow verify that the paginating algorithm recovers when certain events happen
i think it's the hardest problem in all of software development
in this case i think you'll want a text fixture that can dynamically generate data
e.g. if your code is
def fetch_paginated(resource):
while (page := resource.fetch()) is not None:
yield from page
then you'd use some kind of text fixture that dynamically produces new data upon calling fetch
in that world you're no longer able to hard-code inputs and outputs, you basically have to specify your test as a collection of invariants to be asserted
yeah, I see what you're saying, roughly
though in a real world scenario it gets complicated, since you can have multiple clients requesting different chunks of the data with various filter and sort criteria
but I guess that can still be simulated if you design everything well enough
the reason why I'm thinking in the direction of using something like hypotheses is because it seems like there's an insurmountable amount of variables affecting the whole system
and I keep coming back to the realization that if you're unaware that your code breaks in a specific situation, you probably won't write a test that triggers it
def sum(a: int, b:int):
"""
>>> sum(2,3)
5
>>> sum(6,8)
14
"""
return a+b
huh
pytest --doctest-modules
this will catch doctests in addition. cool.
it will make a fine addition, to have tests and self documentation at the same time
oh yeah, better just adding to ini file for auto flag inclusion
# content of pytest.ini
[pytest]
addopts = --doctest-modules
@pytest.mark.parametrize(
'func', [
two_sum,
two_sum_reverse,
with_buffer
]
)
@pytest.mark.parametrize(
'nums, target, indexes', [
([2, 7, 11, 15], 9, [0, 1]),
([3, 2, 4], 6, [1, 2]),
([3, 3], 6, [0, 1]),
([-1, 2, -3, -5, 6, -7], -10, [2, 5]),
([0, 0], 0, [0, 1])
]
)
def test(func, nums, target, indexes):
assert func(nums, target) == indexes
the tests with the last 2 functions fail because they return None
and it's the same if I change the order of func
so it seems like the other parameters nums, target, indexes are getting exhausted after the first function
they're actually receiving nums = [], target = 0
why?
-=[Β΄/~
as much as of I could check within provided code.
import pytest
def two_sum(*args, **kwargs):
pass
def two_sum_reverse(*args, **kwargs):
pass
def with_buffer(*args, **kwargs):
pass
@pytest.mark.parametrize("func", [two_sum, two_sum_reverse, with_buffer])
@pytest.mark.parametrize(
"nums, target, indexes",
[
((2, 7, 11, 15), 9, (0, 1)),
((3, 2, 4), 6, (1, 2)),
((3, 3), 6, (0, 1)),
((-1, 2, -3, -5, 6, -7), -10, (2, 5)),
((0, 0), 0, (0, 1)),
],
)
def test(func, nums, target, indexes):
assert isinstance(nums, tuple) and len(nums) > 0
assert isinstance(target, int)
assert isinstance(indexes, tuple) and len(indexes) > 0
func(nums, target)
there are no empty lists
possibly your functions have side effects
as a choice we can just use immutable list
import pytest
def two_sum(*args, **kwargs):
pass
def two_sum_reverse(*args, **kwargs):
pass
def with_buffer(*args, **kwargs):
pass
@pytest.mark.parametrize("func", [two_sum, two_sum_reverse, with_buffer])
@pytest.mark.parametrize(
"nums, target, indexes",
[
((2, 7, 11, 15), 9, (0, 1)),
((3, 2, 4), 6, (1, 2)),
((3, 3), 6, (0, 1)),
((-1, 2, -3, -5, 6, -7), -10, (2, 5)),
((0, 0), 0, (0, 1)),
],
)
def test(func, nums, target, indexes):
assert isinstance(nums, tuple) and len(nums) > 0
assert isinstance(target, int)
assert isinstance(indexes, tuple) and len(indexes) > 0
func(nums, target)
maybe you're mutating the list?
@static grove βοΈ
e.g. if your test function pop's or del's elements
@pearl cliff I just mentioned it ;b
oops
instead making the list immutable, you can also make a copy of the list in the test function
or change the parameterized mark to a fixture that generates new data on every call
I think using immutable data for unit tests input is just best practice
well, and for data in general inputed to functions
i wish we had frozenlist, frozendict, etc.
tuples are semantically not lists and using them as lists bothers me!
i remember there is frozendict
rejected pep https://www.python.org/dev/peps/pep-0416/
unless they added it later?
a second, I'll find it. it was in one of my books
!e
from types import MappingProxyType
dicty = {"123": 1, "456": 2}
frozen_dict = MappingProxyType(dicty)
print(frozen_dict)
frozen_dict["123"] = 3
@maiden pawn :x: Your eval job has completed with return code 1.
001 | {'123': 1, '456': 2}
002 | Traceback (most recent call last):
003 | File "<string>", line 7, in <module>
004 | TypeError: 'mappingproxy' object does not support item assignment
oh that's an interesting way to do it
!e ```python
from types import MappingProxyType
dicty = {"123": 1, "456": 2}
frozen_dict = MappingProxyType(dicty)
del dicty
print(frozen_dict['123'])
frozen_dict["123"] = 3
@pearl cliff :x: Your eval job has completed with return code 1.
001 | 1
002 | Traceback (most recent call last):
003 | File "<string>", line 6, in <module>
004 | TypeError: 'mappingproxy' object does not support item assignment
TL;DR
MappingProxyType is a read only proxy for mapping (e.g. dict) objects.
frozendict is an immutable dict
so, to insure its immutableness, better creating always as frozen_dict = MappingProxyType({"123": 1, "456": 2})
so there would be no other links to this dictionary left
right, you can discard the binding to the original data and then pass around the mapping proxy
that's neat
probably slower for lookups than a plain dict though
i imagine the "right" way to make a frozendict would be to do it at the C level and just disable __setitem__
too bad there's no SequenceProxyType
could probably make one with sufficient drudgery
if it works like a sequence, if it is immutable, then it is probably SequenceProxyType
so lets just use tuple for this ;b duck typing in a nutshell
blech
or you are worried that it implements too many additional methods?
which SequenceProxyType should not have?
i'm worried because it's semantically the wrong thing and i don't want to be a hypocrite because i always emphasize using semantically correct data types π
what the heck? https://github.com/python/cpython/blob/main/Lib/types.py#L15
Lib/types.py line 15
MappingProxyType = type(type.__dict__)```
π€·ββοΈ using the minimal Sequence implementation as per https://docs.python.org/3/library/collections.abc.html
from collections.abc import Sequence
from typing import TypeVar
TypeVar = TypeVar('A')
class SequenceProxy(Sequence[A]):
def __init__(self, mapped: Sequence[A]) -> None:
self._mapped = mapped
def __getitem__(self, idx: int) -> A:
return self._mapped[idx]
def __len__(self) -> int:
return len(self._mapped)
π
yep that was it, next time I will provide the whole code
thanks
rg
Hi all,
I've been using Python on and off for 10 years, and I just rediscovered a problem that has always irked me.
I made a booboo, removing __init__.py from my tests directory, so when I run python3 -m unittest discover it doesn't find any tests.
python3 -m unittest discover
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
The problem is this passes my automated build process (basically a Makefile) because the return code of that command is still 0.
So my question is, does anybody know of an easy way to make unittest fail if no tests were run? I could check the output for "Ran 0 tests..." but that seems a little hacky.
Limitations:
- I'm using Python 3.9.
- I don't like dependencies unless really necessary, so I'm trying to avoid using
pytest,noseor similar, but if they solve this problem then I would consider it.
Thanks, really appreciate everybody in the Python community.
Actually, I solved my own problem: My favorite solution is to use coverage.py with it's --fail-under option which will fail if no source code is executed.
It is python server, so no
Try asking there
I remember they have a place for homeless languages
The channel is named so
Hey @proper wind!
It looks like you tried to attach file type(s) that we do not allow (.rar). 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.
anyone ever have issues with pytest-asyncio not applying even though its installed?
Can we share our discord's server link here?
i.e., collaborating with Python..
Hey @keen estuary!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
uhhh
hello
-eval
print("jr")
!e /viewauction https://paste.pythondiscord.com/ezuhicepoq.py
@keen estuary :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | /viewauction https://paste.pythondiscord.com/ezuhicepoq.py
003 | ^
004 | SyntaxError: invalid syntax
@keen estuary :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | https://paste.pythondiscord.com/ezuhicepoq.py
003 | ^
004 | SyntaxError: invalid syntax
#bot-commands , also it won't follow your link
And no it won't let you run your bot inside the bot
why not
can anyone help me writing a unittest with pytest for an argparse argument to assert that it is indeed required?
It will time out after a few seconds
You can pass a list of args to parse_args, which it will use instead of sys.argv
So you can test arbitrary combinations of cli args that way
Anyone have good examples of testing with unittest.mock and async methods?
can you be more specific about what you're trying to test? i do this at work somewhat frequently, although it'd be hard to share those examples in a sensible way
I'm testing some of my bot commands for discord.py, creating mocks, like ctx mock. Could you give me some pointers in using mock and testing my code?
phase = SignUpPhase()
ctx_mock = Mock()
@pytest.mark.asyncio
async def test_create_cateogory():
category = 'category'
future = Future()
future.set_result(category)
ctx_mock.guild.create_category.return_value = future
assert await phase._create_category(ctx_mock, category) == category
ctx_mock.guild.create_category.assert_called()
ctx_mock.guild.create_category.assert_called_with(category)
what in the world....
this is going to take a few days to write, since there is so much about pytest that I can learn to make this so nice
There is a partially mocked test suite on @bitter wadi for reference
https://github.com/python-discord/bot/blob/3e34debf2969864cff35ef264806e1ec1e40c0ff/tests/helpers.py#L431-L447
does your code actually use the ctx object anywhere? if not, then don't worry about it. otherwise, i don't think there's anything particularly async-specific when it comes to mocking. it takes a bit of practice and trial-and-error. however, i question your use of Future (i assume asyncio.Future) here - why?
maybe you want ```python
ctx_mock.guild.create_category = AsyncMock()
instead?
ctx_mock.guild.create_category = AsyncMock()
ctx_mock.guild.create_category.return_value = category
General question, how can I improve readability of my integration tests on this open-source project I'm a part of:
https://github.com/Energy-Track-and-Trace/ett-meteringpoints/blob/test/meteringpoints_setup/tests/meteringpoints_consumer/test_handlers.py (Updated link)
Currently each test are very long, and not like something you would think is very maintainable. My biggest struggle is how to test a endpoint that returns a list of objects, like on line 580.
the file you linked is only 202 lines long
Oh you are completely right, I added the wrong link. That's my bad I'll edit it
Sometimes tests are just huge
At work i probably write at least as many test LoC as prod
jeez
I have about 1k lines of code I've written in the past week
and 2k of those lines are not tested
That section at line 580 is totally reasonable @ebon nacelle
Loop over something, construct an expected outcome, assert equality
^
That triple quoted string will go out of date quickly
I'd dispense with it unless you have a tool to keep it automatically in sync with the code
the docstring?
It's not a docstring if it's sitting there at the top level after the imports π
I would at least move those items to the individual docstrings of the test classes/functions
^
you can write plugins for pytest which do actually automatically update docstrings
god I love self documenting features tho
writing them is so satisfying
Got an example?
just make sure you commit often while writing them in case one of them messes up and edits the wrong thing to the wrong file π
But can't we agree that the test at 580 isn't that readable as well as maintainable? This project is still in it's early stages so I'd expect lots of stuff to change, therefor the tests open for changes as well
No I thought it was perfectly readable
not super much, but its defintely possible to collect all tests with pytest and get their metadata
There's a library for automatically exporting a docfile of all pytest files, but its not the best.
!pypi pytest-docs
@ebon nacelle it's not flexible if your design is actively changing and WIP
In that case then yes, you don't necessarily want to test properties that you aren't comfortable testing
About the "docstring" you are right, that's not optimal. The idea were to have some kind of system to see what gets tested where. As you might have noticed, the tests assert multiple things, so it's an attempt to get and overview
@pearl cliff that's an example of automatic test docs, but I think it would be more useful to read the source of that plugin and migrate it to be a new plugin π
That or just accept that you will have to change your tests frequently. That also isn't a bad thing necessarily
yeah
the bad thing is when you fully refactor your code including public apis and the tests still run perfectly 
will neither confirm nor deny that it was both a nice feeling and bad feeling if that happened to me last week hypothetically
sounds pretty cool with the pytest-docs gotta look into that π
However I still disagree with the tests being fine, I'm not satisfied with how "confusing" they are as of now. Gotta figure out what to do lol
i would like to point out that module is buggy-- i would not use it
You mean in pytest-docs?
curious what a self-documenting feature is?
A function will always return something. A function without an explicit return will return None.
@floral grotto
!e py def func(): pass print(func() is None)
@spiral arch :white_check_mark: Your eval job has completed with return code 0.
True
:incoming_envelope: :ok_hand: applied mute to @woeful whale until <t:1632482670:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
you can test anything that can be checked for True!
!e
def test_your_things():
# arrange
first_number = 6
second_number = 2
string_with_stuff = "stuff"
# act
is_stuff_in_stuff = "stuff" in string_with_stuff
calculated_sum = first_number + second_number
# assert
assert is_stuff_in_stuff
assert calculated_sum == 8
test()
!e
def solve(nums, div):
for i in nums:
j = i % div
x = i + j
nums.insert(i, x)
return nums
solve([2, 7, 5, 9, 100, 34, 32, 0], 3)
@hexed sierra :warning: Your eval job timed out or ran out of memory.
[No output]
i made a simple program that no one can run
Because you made the nums bigger each time in a for loop. Was that intentional?
!e
def solve(nums, div):
for i in nums:
result = []
j = i % div
x = i + j
result.insert(i, x)
return result
solve([2, 7, 5, 9, 100, 34, 32, 0], 3)
@dry walrus :warning: Your eval job has completed with return code 0.
[No output]
i have no idea
!e
def solve(nums, div):
result = []
for i in nums:
j = i % div
x = i + j
result.insert(i, x)
print(result)
return result
solve([2, 7, 5, 9, 100, 34, 32, 0], 3)
@dry walrus :white_check_mark: Your eval job has completed with return code 0.
[0, 4, 8, 7, 9, 101, 35, 34]
returning True has nothing to do with whether a function is testable
a test is basically only a function that runs the function that is to be tested and then compares what the function returns (or something else, it can be anything really) has the expected value(s)
In that case, you'd want to test that what was printed was what was expected to print.
!e print(1+2)
@fading ermine :white_check_mark: Your eval job has completed with return code 0.
3
:o
hi what are the best content to start with unit testing and penetration testing?
!d contextlib.redirect_stdout
contextlib.redirect_stdout(new_target)```
Context manager for temporarily redirecting [`sys.stdout`](https://docs.python.org/3.10/library/sys.html#sys.stdout "sys.stdout") to another file or file-like object.
This tool adds flexibility to existing functions or classes whose output is hardwired to stdout.
For example, the output of [`help()`](https://docs.python.org/3.10/library/functions.html#help "help") normally is sent to *sys.stdout*. You can capture that output in a string by redirecting the output to an [`io.StringIO`](https://docs.python.org/3.10/library/io.html#io.StringIO "io.StringIO") object. The replacement stream is returned from the `__enter__` method and so is available as the target of the [`with`](https://docs.python.org/3.10/reference/compound_stmts.html#with) statement:
```py
with redirect_stdout(io.StringIO()) as f:
help(pow)
s = f.getvalue()
``` To send the output of [`help()`](https://docs.python.org/3.10/library/functions.html#help "help") to a file on disk, redirect the output to a regular file...
if I were you, I'd test that your function generates the right data, and just assume that it properly writes it as JSON, since doing that is quite easy and therefore not really worth testing
I mean, run your stuff by hand a couple times to make sure it's writing out the JSON, but there's no need to unit test all that
you should write tests that have genuine benefit
as opposed to testing every conceivable thing your code does
i/o is notoriously difficult to unit test
and mocking and patching are tricky to get right
if I were you, I'd assume the built-in JSON libraries work correctly.
It happens to be true, and assuming that will save you a pile of effort
I'm imagining that you have a function like this ```py
def compute_a_buncha_stuff_then_save_it_as_JSON(inputs, output_file_name):
...
if so I suggest you rewrite it just a little like this ```py
import json
def compute_a_buncha_stuff_then_return_it_as_a_list_of_dicts_or_something(inputs):
...
def compute_a_buncha_stuff_then_save_it_as_JSON(inputs, output_file_name):
stuff = compute_a_buncha_stuff_then_return_it_as_a_list_of_dicts_or_something(inputs)
with open(output_file_name, 'w') as outf:
json.dump(stuff, outf)
then test that first function, and assume that the second one works fine
look at that second function: it does two very simple things. The first thing it does, you've thoroughly tested; the second thing is built into python, and therefore doesn't need testing. It has no ifs or loops or anything. Guess what: you don't need to test it
ok ok you should run it once or twice just to make sure there's no brainos. But you don't need anything beyond that.
this is just a taste of what's called "Test-Driven Development". I'm not a True Believer, but there are some good ideas in there
well, 100% coverage would be great; it's just that it's not free
that last 5% will take a lot of time and add a lot of complexity; it's just not worth it
with TDD you are just doing your tests first. so you just move where you run your app from to the test file rather than a script you probably using instead.
that way you don't have to think really. as the tests drive the code. and most of the unhappy paths get catered for too. as you start with failing tests
i.e. if you had a test now called test_write_to_file . your tests will fail
so then you make the test pass.
by coding that functionality
when you code. u normally code the short cut happy path. and run some script that does what your writing it for. but instead of that 'script' . instead run a test
that's the ideal.
In practice it's often very difficult to do TDD
I almost always start out doing it, but sometimes have to abandon it
agree totally. but i think 90% of people do them wrong. even me. and TDD is a holy grail
i mean even think about them wrong
when you get it right. you feel the flow. and you realise doing them afterwards is almost pointless
and probably tests the wrong things as it wont pick up the unhappy paths
and doing them after. might lock in functionality rather than behaviour. it might be a bad thing
in theory you're not supposed to test the implementation, and instead just test the contract. I understand the reasoning, but again it's often hard to do that right
anyone here read obey the testing goat?. i quite enjoyed that one
sounds familiar
sounds like the sort of thing whose examples are in Smalltalk or something though π
i think it was django 2. and i did it but converted it to django 3 but followed along. made it a little hard
cool. just found it online. still around https://www.obeythetestinggoat.com/book/chapter_01.html
Hey folks, we are launching a npm package in beta, it generates unit tests in bulk for JS TS and Python. We hope to accelerate the unit test production and make developer life a bit easier. https://www.producthunt.com/posts/ponicode-cli check it out and share your feedback
Faster software development, more robust code & high code coverage directly from your command line are now possible thanks to AI. Generate unit tests in bulk for your TS, JS & Python projects with the most relevant test scenarios. https://www.npmjs.com/package/ponicode π
does this let you save and inspect the generated tests? interesting idea
i'd be curious what the underlying ML model is like
ah, i see
Ponicode CLI accelerates developers by- creating and bootstrapping your unit test file with a test suite per function - writing 5 test scenarios for each functions- including both happy paths & edge cases to each test suite.
so it's not like mutation testing, fuzzing, etc. where it generates a huge amount of inputs
it "just" auto-generates tests for your code when you don't already have tests
is this built on copilot or is it something different? where did you get the training data?
not sure it's a good idea. maybe it is if your boss insists you need to have the coverage just because and you have to do it, but for the sake of the code being correct it really makes more sense to apply unit-tests wisely and make sure they are correct firstly and don't overdo with it, then you can refactor it, etc, then it's really useful
if I understand it correctly, it will just copy the code to the unit-test framework
talking about edge cases makes sense, but the problem with that is: YOU have to DEFINE what you expect it to do in those cases, should it stop working/continue working as much as possible/inform/etc ?? it's the matter of design and you need to agree on that when you're coding
well, it creates the points for you, so maybe good at elast that, you don't need to type much and then read carefully and make decisions... I guess
many companies blindly apply that the coverage needs to be at least that percentage or as much as possible, but it's silly, if you are keeping good architecture and things are good decoupled then you surely don't test everything (like you don't need to test every method, etc), you test things that are not very clear, complicated or if your design has agreed on a specific rule/goal/result
if you change one method and it brakes another method in another class then yes, you test it, but it's probably solvable even better by changing the architecture and decoupling things
i recently saw it said that code coverage metrics are most useful when you are first starting a project, because they show you all the parts of the codebase you forgot about when you started writing your test suite
but blindly copying the same logic to the unit-test doesn't make the logic any better... the key point of unit-test is testing if the logic is correct, but you can't do it with the copied logic, that was my whole point of argueing that coverage test alone does not mean anything if you are not aware what you are doing
in the end, I did not try the project, maybe the project does work differently than I am imagining, in that case my apologies
best examples when the unit-tests are helpful is about CONSISTENCY: for example, if you only add positive numbers then your sum must also be positive, if you get a negative number then it's a consistency violation, or let's say you only add even integers, then the sum must also be an even integer, or if you calculate probabilities of something and it can happen only one of them, in that case adding them up must be exact;y 1, things like that
if you have a big project, very often consistency checks lead to discovering bugs that are there for a long time and you don't notice them π a very powerful thing
It sounds like you're talking about testing "properties"
And I agree, that's a better way to test
I think in this case it just generates "5 test cases" for you
Unclear if those are properties, or individual examples, or both, but i would guess it's the latter
I guess one of us could try it π
Why you pinged me?
you are a helper
I am volunteer
I am helping when I am able to do it
Please, don't ping random people
ok sry
There is a single ' after 4.45
So it thinks the rest of the line is a string, but it doesn't find the end of the string
I suggest reading the error messages, they exist for a reason
i know the error message why it happenning
it's the expected output
and it should pass the tests not fail
Ah, sorry then
Let me see
it looks like ELLIPSIS doesn't have any effect for tests, but it does look like the traceback needs to be indented
https://docs.python.org/3/library/doctest.html#what-about-exceptions
>>> raise ValueError('multi\n line\ndetail')
Traceback (most recent call last):
...
ValueError: multi
line
detail
i'm not sure about the 2nd ellipsis, let me read further
>>> r = add_integer() # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
TypeError:
that should work
When the
IGNORE_EXCEPTION_DETAILdoctest option is specified, everything following the leftmost colon and any module information in the exception name is ignored.
this is what i did
>>> r = add_integer() # doctest: +ELLIPSIS, +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
TypeError:...
the ... in TypeError is ignored
oh yea
and the +ELLIPSIS has no effect here
it also looks like youre expected to indent the ...
def add_integer(a, b):
""" Add integers
Example:
>>> r = add_integer() # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
TypeError:
"""
return a + b
r = add_integer() # doctest: +ELLIPSIS, +IGNORE_EXCEPTION_DETAIL
Expecting:
Traceback (most recent call last):
...
TypeError:...
why can't i do something like this
>>> r = add_integer() # doctest: +ELLIPSIS, +IGNORE_EXCEPTION_DETAIL
...:
...
TypeError:
i think doctest just requires Traceback (most recent call last):
that's just how they decided to do it π€·ββοΈ
think of it like a pattern that the output has to match
ok thx
okay, so I would say, first
In TDD, How do you know what tests to write when your logic is changing
that there are degrees of TDD?
there's the Super-Hardcore-Make-Sure-Compile-Fails-And-Always-Write-Tests-First style
I'm not a fan of that
and in particular, when experimenting, you don't even know what the intended outcome is
I feel that's what is advertised generally in most resources
so writing tests first can be π₯΄
okay so my company is BIG on TDD
but we're quite practical about it
Yeah that's exactly how I feel
on the other hand
there are cases
where the intended result is super clear
okay, for example
I was adding methods to a class that represented a date range
so
I wanted to add a clip method and a expand method
so basically reduce the bounds of the current range if they're outside the passed range
and expand the bounds if they're less than those of the passed range
in those cases
intended behaviour is very clear
so TDD, in the sense of "write tests first", works well
Yeah that's exactly it
but
it's not only limited to those cases.
there is a school of thought that basically says
once you have identified a reproducible bug
you should write a test case that catches it first
and THEN fix it
I agree with that
because if there was a bug clearly your suite is deficient, right (otherwise it wouldn't have passed)
that's part of the idea that
your test should actually work
because
oh i see
right and you want to catch the bug again down the line
so if you haven't seen your test fail with your existing code, how do you know it actually catches the bug?
So do you remove the test once the bug is fixed?
no
just like you don't remove your tests once your code is working
because your tests are there to assure you of your code's functionality
even in the face of further changes
but wont the test fail?
i.e. to catch regressions
or is that a scenario where you want it to fail once it is fixed?
okay, maybe I should give an example
say you have a function divide(a, b)
def test_divide_int():
assert divide(6, 2) == 3
def test_divide_float():
assert divide(3, 2) == 1.5
and assume further that you want to have special behaviour for dividing by 0: you want your function to return 0
but you didn't write a test for that
so in production, there's a divide(13, 0) somewhere, and that throws a ValueError instead of returning the expected 0
now you know you have a bug
step 1: add to test
def test_divide_zero():
assert divide(5, 0) == 0
and now, when you run your tests, this one will fail
THEN you fix your divide function
and you know it works when your test passes
it's basically a special case of this
I see now that makes sense
that said, actually writing tests is a lot more important than when you write them, IMO
Thanks so much for the explanation
the nice thing about writing tests first is that you can be sure they all fail (as they should)
np! π
but sometimes you just get tired of writing tests
I HATE writing tests
You should turn this set of messages into a medium article for the jr devs
I could, but would anyone actually read it π
I actually would like to start blogging but I don't know if anyone would follow me
Yeah those of us whose managers decide to get more into TDD so we scout the net to understand why do this
Well youβve got an audience here at this discord server for a start
all right
I will see if I can come up with something
you wanna know when it's done
?
Yeah ping me please
How to mock os.path.exists called inside certain function in my music.py file?
@mock.patch("music.get_track_paths.os.path.exists") do not work (causes ModuleNotFoundError: No module named 'music.get_track_paths'; 'music' is not a package_ error)
I'm not completely sure, but I believe in those cases you just patch os.path.exists directly. @mock.patch("os.path.exists")
Unfortunately, I have to return two different values for this check (one inside the mentioned function and another one in an another function) - so have to specify function' name
In other words - I have to differentiate between two calls of os.path.exists (and, unluckily, two opposite values π
) in one unit test
code_file.py
import os
def second_function():
return os.path.exists("/foo/bar")
def my_function():
second_inside_call = os.path.exists("/i/love/mocking")
if not second_function() and second_inside_call:
return True
return False
test_file.py
from code_file import my_function
from unittest.mock import patch
@patch("os.path.exists", return_value=False)
@patch("code_file.my_function.os.path.exists", return_value=True)
def test_my_f(first_mock, second_mock):
assert my_function()
Good luck - both for you and me π
Use side_effect.
This is copied from the python docs (https://docs.python.org/3/library/unittest.mock.html):
>>> def side_effect(value):
... return value + 1
>>> m = MagicMock(side_effect=side_effect)
>>> m(1)
2
>>> m(2)
3
Since you have the parameters (value) you can do different things in the side_effect function.
To apply this you can either do
@patch("os.path.exists", new=m)
def ....
Or
@patch("os.path.exists")
def test_my_f(first_mock):
first_mock.side_effect = side_effect
assert my_function()
I think.
Still - how to differentiate calls?
Like i said, by looking at the value, or i guess you could look at the call_count inside... there is no pretty solution afaik.
It could be cheeky - but give me a working test (test_file.py) with correctly passed assert, I politely please π
Do they have the same arguments both times?
Replace os.path.exists with your own function
Use the new=my_special_function argument
What arguments?
I call test_my_f once and that's it - the test should pass
No, the calls to os.path.exists, inside the test
I meant something like this
m = Mock()
def side_effect_1(path):
if m.call_count > 1:
return True
return False
def side_effect_2(path):
if path == 'exists':
return True
return False
m.side_effect = side_effect_1
# m.side_effect = side_effect_2
class Dummy:
@staticmethod
def func(path):
return path
@patch.object(Dummy, "func", new=m)
def test_this():
assert Dummy.func("nope") is False
assert Dummy.func("exists") is True
(Dummy class only exists for me to have a namespace to use with the @patch)
However, both side_effect solutions are - in my opinion - fairly ugly as the mock needs to "know" a lot about how the code works. Perhaps mocking second_function altogether is a better solution.
(edit).. actually side_effect_2 could be alright
Arguments are explicit - the calls won't be parametrized anymore
Yea, not elegant.
For my case I can extract these checks into another one-time functions with partly sense, although it's awful with 100 calls π
hi
why the test is not matching what it is expected
help me pls this makes no sense
Out of curiosity what's the use case here? Are they 2 different directories or the same directory twice?
My written downloader service uses two different checks:
- one for existence of ready to play tracks (ffmpeg for converting them from any format requires already made directory) directory
- one for existence of downloading track - do not download it again π
So the calls (and its path arguments) are different
Do you need catch an exception during testing or so?
What do you want to achieve?
The code isn't self explanatory π
sorry, i truly dont know what the issue is. but i do think that the +ELLIPSIS isn't necessary here, the ... is always recognized
are you missing a : in the Traceback line?
at the end, after )
try fixing that
ππ» hello
Hey everyone π
I want to implement unit testing in my project mitype.
Here is the link to the project - https://github.com/Mithil467/mitype
I am very new to unit testing and have learnt basics of pytest and am planning to use it. But apart from that, can someone give me some pointers/tips to what should I be aiming for with this kind of a project? Is there anything I should know before starting out? Maybe some existing project out there that I can refer to.
@brittle brook write your code to do as little i/o as possible "internally" - push as much of the console and disk interactions to the "edges" of your application as possible
Use dependency injection so you can explicitly pass in mock things instead of using patch
And consider using pexpect to test the actual CLI/TUI
Hey @pearl cliff
shudder ... "pexpect"
Thank you very much! @pearl cliff
hello im trying to make a unit test ```py
import unittest
def add(x, y):
"""Add Function"""
return x + y
def subtract(x, y):
"""Subtract Function"""
return x - y
def multiply(x, y):
"""Multiply Function"""
return x * y
def divide(x, y):
"""Divide Function"""
if y == 0:
raise ValueError('Can not divide by zero!')
return x / y
def if_string(x,y):
pass
"""check if string is entered function return error"""
class TestCalc(unittest.TestCase):
def test_add(self):
self.assertEqual(add(10, 5), 15)
self.assertEqual(add(-1, 1), 0)
self.assertEqual(add(-1, -1), -2)
def test_subtract(self):
self.assertEqual(subtract(10, 5), 5)
self.assertEqual(subtract(-1, 1), -2)
self.assertEqual(subtract(-1, -1), 0)
def test_multiply(self):
self.assertEqual(multiply(10, 5), 50)
self.assertEqual(multiply(-1, 1), -1)
self.assertEqual(multiply(-1, -1), 1)
def test_divide(self):
self.assertEqual(divide(10, 5), 2)
self.assertEqual(divide(-1, 1), -1)
self.assertEqual(divide(-1, -1), 1)
self.assertEqual(divide(5, 2), 2.5)
with self.assertRaises(ValueError):
divide(10, 0)
if name == 'main':
unittest.main()``` i made a unit test so it gives an error if u divide with 0 i want to make a unit test now if there are entered string and not number
can some one help me
def if_string(x,y):
if isinstance(str, (x,y):
print("string input")
return True
else:
return False
I would recommend applying parametrization to your tests btw
https://stackoverflow.com/questions/32899/how-do-you-generate-dynamic-parameterized-unit-tests-in-python
pytest has it clear as decorators https://docs.pytest.org/en/latest/how-to/parametrize.html
unittest not sure how, parametrized library look cool though https://github.com/wolever/parameterized
I would recommend pytest as first choice.
In unittest you can just loop over parameters and use self.subTest at each pass
yes that was the problem
hello since this is a testing channel
I have a question related to pytest
or if someone could check #help-carrot
what's the question?
Hi, I'm pretty new to testing. I'm using pytest and I want to test the following function and other's like it:
def get_users(path_to_file: String) -> list:
df = pd.read_csv(path_to_file, names=['l_name', 'f_name'], header=None)
users = []
for _, u in enumerate(df.values):
users.append(f'{u[0]},{u[1]}')
return users
So far I have the following attemtp to verify the return is a list but it fails with a file not founs error
def test_get_users():
arg = "some file path"
assert isinstance(get_users(arg), list)
I cound do with some guidance on this, can I create a fixture or a mock file to test this and other functions with?
should I reserve a channel
esp. since you already tried once :)
bet
so like I am trying to test this function
that draws a circle, I am trying to check the parameters
ok
def test_draw_shape_circle():
"""This will check if the circle fits within our boundaries """
shape, color_code, x, y, length, height = draw_shape(shape="c", color_code="green", x=-250, y=0, length=70,
height=90)
assert shape == "c"
assert abs(x) > 400, "your staring point is not within the bounds"
assert (abs(x) + length) > 400, "your length is not within the bounds"
assert y > 400, "your staring point is not within the bounds"
assert (y + height) > 400, "your height is not within the bounds"
ok
def test_draw_shape_circle():
"""This will check if the circle fits within our boundaries """
shape, color_code, x, y, length, height = draw_shape(shape="c", color_code="green", x=-250, y=0, length=70,
> height=90)
E ValueError: not enough values to unpack (expected 6, got 5)
test_drawing_shapes.py:18: ValueError
=================================================================================== short test summary info ===================================================================================
FAILED test_drawing_shapes.py::test_draw_shape_circle - ValueError: not enough values to unpack (expected 6, got 5)
HOW
ahh, ok
the thing is the other function worked
def test_draw_shape_rectangle():
"""This will check if the rectangle fits within our boundaries """
shape, color_code, x, y, length, height = draw_shape(shape="r", color_code="red", x=-100, y=100, length=150,
height=90)
assert abs(x) < 400, "your staring point is not within the bounds"
assert (abs(x) + length) < 400, "your length is not within the bounds"
assert y < 400, "your staring point is not within the bounds"
assert (y + height) < 400, "your height is not within the bounds"
can you show the end of draw_shape ?
hehe
yup wait I am changing it rn lemme check
cool
Pycharm printed its loaded my rc file in coverage, but it didnt actually load it, how to fix this? cos in cmd it works fine but not in pycharm coverage
Would anybody be able to help out with this?
I need to write an unit test and I should mock everything
def _dispatch(self, url: str, payload: dict) -> Any:
self.__logger.debug(f"Sending request : {payload}")
token = self.__auth_service.auth(scope=self.__cognito_scope)
response = self.__http_client.post(full_url=url, auth=token, request_json=payload)
return response
The thing is, I've never done any of that...
Yeah you will need to mock auth service and http client. That said why use __?
Speaker: Lisa Roach
One of the most challenging and important thing fors for Python developers learn is the unittest mock library. The patch function is in particular confusing- there are many different ways to use it. Should I use a context manager? Decorator? When would I use it manually? Improperly used patch functions can make unit tests us...
"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...
!d unittest.mock
New in version 3.3.
Source code: Lib/unittest/mock.py
unittest.mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.
unittest.mock provides a core Mock class removing the need to create a host of stubs throughout your test suite. After performing an action, you can make assertions about which methods / attributes were used and arguments they were called with. You can also specify return values and set needed attributes in the normal way.
Hi, whatβs the best way to test APIs in Python? Iβm using Postman. Should I hit the API directly or test from my local host?
depends on the type of test you want to perform
how to unit test
best way to apply pytest library as a first step for unit and integration tests
and using testing client/library special to the API framework you use
Hello, I am trying to create an automarker for a course I am teaching this semester, I am looking into mock and patch. I am able to mock input with a sequence of inputs in https://pastebin.com/JmKtjv11 , but when I try to separate the testing from the students submission file I am confused about how to apply the patch function https://pastebin.com/70NWfauG . Would anybody be able to give me some pointers? Additionally once I am able to mock the inputs, does anybody have any advice on how to mock print statements so that each print statement is stored in a list which i can compare against the model output?
Note that due to the universities online code environment I cannot install any additional packages or software without a lot of headache, so would prefer to get this implemented with core python if possible
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
U a asking students to write
amount_of_people=int(input())
for person_number in range(amount_of_people):
name=input()
print (f"Hello {name}, you are person {person_number + 1} to check in today")
Β
And u wish input to match desired output in a test?
Are students allowed to see and run your tests?
Yes
The way our system works is that we define a number of criteria and then create a CSV which puts a 1 or a 0 as to whether they met the criteria, so assuming that the student passes the test they would be given a 1
But I would like students to be able to test with predefined inputs with known outputs
and then running on random inputs at the end
But am having trouble figuring out how to patch inputs so that they are given in a sequence
The code in my first pastebin achieves this when I simply mock input, but cannot figure out how to do this in a separate file in a more unittest way (the second pastebin)
Since this is a very beginner course I would like to keep any unnecessary to the problem code out of the file where they will write the solution
IMO a bit of dependency injection would look good here.
Would you mind explaining this?
A moment, going to reach pc, smartphone is not comfortable
Thanks!
https://pastebin.com/MBH3Y49z
This would be parameter injection approach to test it
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
run tests as python3 -m doctest -v filename.py
out of curiosity lets try to finish your way too
Oh and we can simplify your case further with
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
this parameter injection version requires even less code to do that
so... lets see next way..
Will have a look through both now!
One caveat is
Is there a way to do this kind of testing without the code being in a function?
Functions will be fine in a few weeks, but right now I am teaching absolute beginners from humanities subjects
So trying to keep things as basic as possible
heh, you are making the challenge
write testing without functions and without third party packages
If needs be I can just wrap the code in a function and add comments saying #DO NOT CHANGE THIS
haha
I think it should be possible
Another caveat is, in your code you replace input() with input_number(), is it possible to have it remain as input()?
To avoid having to explain that these are special functions which have been created for assignments
E.g. in the first pastebin I posted, the input() is not the builtin input but a mock to replace it, but it appears as if it's the builtin to somebody who doesn't know how to check
Ok I have it working!
Did require a function though
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I made my way working too
amount_of_people = int(input())
for person_number in range(amount_of_people):
name = input()
print(f"Hello {name}, you are person {person_number + 1} to check in today")
import subprocess
from sys import stdout
result = subprocess.run(
["python", "example.py"], input=b"3\nMiles\nBecca\nGeorge", capture_output=True
)
answer = b"Hello Miles, you are person 1 to check in today\nHello Becca, you are person 2 to check in today\nHello George, you are person 3 to check in today\n"
assert result.stdout == answer
print("the result is correct!")
run python testing.py as a test run
blackbox testing ;b
to make it more beautiful we could split the lines
import subprocess
from sys import stdout
input_lines = [
"3",
"Miles",
"Becca",
"George",
]
result = subprocess.run(
["python", "example.py"],
input=str.encode("\n".join(input_lines)),
capture_output=True,
)
answer_lines = [
"Hello Miles, you are person 1 to check in today",
"Hello Becca, you are person 2 to check in today",
"Hello George, you are person 3 to check in today",
]
answer = str.encode("\n".join(answer_lines) + "\n")
assert result.stdout == answer
print("the result is correct!")
as a more elegant way
u a welcome. π
a bit of lesson to me too
in situations like that I needed apt install expect before
(interacting with external process that requires manual input)
now I know how to go without it
hey i am using sqlalchemy and unittest and trying sqlalchemy mocking libraries to mock session execute of select objects
having difficulty ... anybody have any advice or have done this before?
Can mock-alchemy or alchemy-mock be used to mock session.execute(selectObject).where(...).scalars.fetchAll?
https://stackoverflow.com/q/69546839/6429049?sem=2
How to mock an inner function?
def a():
def b():
return "I want to be mocked"
print("sth")
result = b()
if result is not None:
print(result)
assert result is None
print("Nice")
from unittest.mock import patch
from sth import a # import ^ a() function
@patch("sth.a")
def test_if_properly_mocked(mocked):
mocked.return_value.b.return_value = None
a()
Unfortunately, don't work π¦
I have never used mock, but I would have guessed: mocked.b.return_value since b is just inside a which is mocked in this case
(is it strange that I started "I want to be mocked" in the melody of I want to break free)
Soooo... no, isn't working π
ok, so what was not working in your code?
https://stackoverflow.com/questions/12523189/how-to-mock-nested-functions/32956627 Seem to suggest the same approach as oyu had from the start.
Try it on your own, seriously π
I don't think it's possible to patch b from outside a in your example; there seems to be some confusion in the SO thread about what a nested function is
b does not get defined until a runs
it's no different to:
>>> def a():
... b = 5
is there a reason for b to be defined inside a? usually the reason for that is that the inner function cannot be constructed until the outer function is called
Exactly as I expect to behave
I eventually declared it outside but it's a still good question
if it can be declared outside then yes that'd be my suggestion
how to mock an async method in a pytest env?
are you using unittest.mock to do the mocking? you can use AsyncMock instead of Mock
ah, no, i was not using that
how do y'all mock discord py classes for tests?
for example?
await send(content=None, *, tts=None, embed=None, embeds=None, file=None, files=None, stickers=None, delete_after=None, nonce=None, allowed_mentions=None, reference=None, mention_author=None, view=None)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).
Sends a message to the destination with the content given.
The content must be a type that can convert to a string through `str(content)`. If the content is set to `None` (the default), then the `embed` parameter must be provided.
To upload a single file, the `file` parameter should be used with a single [`File`](https://discordpy.readthedocs.io/en/master/api.html#discord.File "discord.File") object. To upload multiple files, the `files` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.9)") of [`File`](https://discordpy.readthedocs.io/en/master/api.html#discord.File "discord.File") objects. **Specifying both parameters will lead to an exception**.
To upload a single embed, the `embed` parameter should be used with a single [`Embed`](https://discordpy.readthedocs.io/en/master/api.html#discord.Embed "discord.Embed") object. To upload multiple embeds, the `embeds` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.9)") of [`Embed`](https://discordpy.readthedocs.io/en/master/api.html#discord.Embed "discord.Embed") objects. **Specifying both parameters will lead to an exception**.
@magic dawn I have a method that takes a messageable object and uses the send command, I want to mock it and pass my mocked object for the test
I think you basically have two options: make the event loop fixture module scoped, or make your fixture sync and run its own event loop internally to interact with async resources
I think theres probably a very good reason for why the event loop fixture is function scoped by default; you dont want eg background tasks leaking across tests, that would be very bad
the latter option obviously limits you somewhat but so far Ive been able to work around it
eg if you want to connect to a database asynchronously at session scope to prepare it, you can make the fixture synchronous and internally spawn an event loop to do io and then close it
you wont be able to pass async resources into your tests because they'd be bound to the wrong event loop, and you may have to eg dispose pooled connections manually before yielding, but ive been able to work around these limitations so far
Hello
can someone help me run tests for starlette locally?
Here is the repo https://github.com/encode/starlette
I'm also not sure how to go about creating a new pull request
but my code change is minimal and I need to run the additional tests I've added locally
I've never ran a python test so help is appreciated
I think i figured out how to run the test using pytest from the cli
if i have some x = getattr(module, 'thing') and then do getattr(x, 'other_thing') what would I refer to these as?
I'm getting the attribute (thing) from the module, then i'm getting the attribute (other_thing) from the module attribute π€
I was thinking of calling it:
def get_sub_attribute_from_module( ...
does that make sense?
Hi, I'm on mobile so I couldn't test it. You can try if you want:
functools.reduce(getattr, ["Thing", "other_thing"], module)
sorry i was mainly wondering about whether the naming made sense rather than how to more succinctly get the value, thanks tho
@floral grotto Check out TDD with Python book: https://www.obeythetestinggoat.com/
how do i check a dict is a subset of a different dict?
It'd be nice if it supported <= directly, but you can do set(d1) <= set(d2)
ah cool
In [1]: d1 = {'a' : [1,2]}
In [2]: d2 = {'a' : 'hrm'}
In [3]: set(d1)<=set(d2)
Out[3]: True
In [4]:
would this be considered True? I'd consider this false, as it's just checking the keys.
but maybe people just refer to the keys, idk
@cobalt ore yes, that's exactly what it does. it depends on what you mean by "subset", and why we don't have more set operations on dicts - because the core devs thought for years that it was potentially confusing. but dicts generally work on their keys, e.g. iterating. and that's how this particular example works: recall that iter(d1) iterates over d1.keys(), and set() just consumes an iterable to produce a set, so set(d1) is really set(iter(d1.keys()))
yeah, i guess i'd assume that in order to be a subset the values associated with the keys must be too... but maybe people would just think about the keys π€
i'm pretty sure it the whole purpose of a dict is the association, not the set of keys it has
it's more an artifact of how python iteration on dicts works--I see no connection to subsets or supersets of mappings
i think it just depends on your intended meaning
and you could do set(d1.items()) for the set of key,value pairs (as long as the values are hashable)
maybe there's a use case for a "non-hashing set" where it checks for equality the slow way, with ==/__eq__
Hi anyone have idea about code coverage through pyunits, for example my mail code is doing file handling or writing a file and reading it how can I cover that in code coverage
you have several example in this article: https://www.sealights.io/agile-testing/test-metrics/python-code-coverage/, DO not know if it answers your question
coverage.py is quite powerful
Dicts themselves don't support set ops, but dict.keys() does support all the operators and methods - d1.keys <= d2.keys() works directly.
items() is also, if values are hashable.
I know
But if I hear subset, I think how I explained
Which I pointed out as perhaps I'm wrong in thinking in those terms
What you're outlining wouldn't be a subset to me, just the keys could be
i always forget about this, ty
you should ask in the https://gitter.im/encode/community
and you should tell them to use tox waves stick
What's Tox??
It's a tool for test automation
You specify a bunch of Python versions, and it creates virtualenvs for each, installs your dependencies and your package into them, then runs tests. That way you can know every version works, installing works (since it uses the sdist not direct from your repo), etc.
Often I find it's so easy for your test tool to pick up the toxinidir rather than the installed package
Hi, dudes, hope everybody here is ok. I wrote a test for a function that calls zipfile.ZipFile(io.BytesIO(binary_content), 'r'). Every time I run that test I got exception BadZipFile: Bad magic number for central directory. But, if I run the same code outside test, everything is fine. As far as I know, that exception is raised after the following zipfile's check: centdir[_CD_SIGNATURE] != stringCentralDir. I'd like to know if there is a general solution to that problem
binary_content variable comes from requests response content
Has anyone faced python selenium headless script failure which works with GUI ? Using detain 11
*Debian
okay wow

