#unit-testing
1 messages · Page 4 of 1
in IDE, yes. when copy pasting directly to Discord? no.
You should have done it in your IDE and then copied to discord heh. Much faster.
¯_(ツ)_/¯
Hey! @proud nebula
Hello?
class MongoDBWrapper:
def __init__(self, host, port, db, collection):
self.collection = motor.motor_asyncio.AsyncIOMotorClient(host, port)[db][collection]
async def insert(self, documents, many = False) -> None:
if many:
await self.collection.insert_many(documents)
else:
await self.collection.insert_one(documents)
how to unittest insert? I dont understand how to mock self.collection and insert_* methods 
I use built-in unittest.mock
That’s a common problem with stateful classes. I would write a insert function outside of the class, that accepts a collection and the other inputs.
That one can easily be unit tested - you have control over the input and can stub/mock/monkey patch it.
Your class would then call the state-less function. And no need to unit test that part.
If you don't like to extract code from the class, but still want to unit test, then you have to figure out a way to mock or monkey-patch motor.motor_asyncio.AsyncIOMotorClientthat is used in the init function of your class. The unit test will only verify if your many parameter is used correctly. The rest is only mocked out code. Are you sure this is a good fit for a test?
Yes.
It’s a good start to write tests for those. When lower level tests like util/helper tests overlap other tests that are on a higher level that cover the helper code: you can probably remove the lower level ones. I know that many fear removing tests, but that’s ok!
Lower level tests mean when they fail you have much a clearer understanding of what the problem is.
Plus it makes mutation testing much faster if you can make it use the lower level tests first or only.
I think it is a balance to find within the team, having unit tests that are “too low level” is at risk to slow down refactoring, since they define an implementation detail. From my experience it can be a good idea to unit test on a level up higher, but not too high up in the stack. Up there, you’ll very likely end up writing a lot of mocks. That’s painful. Too low level tests can be annoying too: you change one thing an a bunch of tests fail. Ideally, very few (at best one) test should fail.
During development, TDD is a good tool. But it is allowed to delete tests too. Nowadays I usually do REPL Driven Development, that is very much TDD-and-throw-away - sometimes too much of throwing away. It’s always a thing to have in mind, finding the balance (and ignore that coverage-metric).
Yea, that's a good point. If the lower level stuff is clean and reusable, then it's good to have unit tests. If they are just implementation details then maybe not so much.
:incoming_envelope: :ok_hand: applied timeout to @warm relic until <t:1681027127:f> (10 minutes) (reason: duplicates spam – sent 4 duplicate messages).
The <@&831776746206265384> have been alerted for review.
Does anyone know good examples of open source projects with good structure of unit tests? When people use fakes and stubs instead of just mocks and separate integration/unit tests? Especially interested in database/broker interactions
Maybe this article could generate some ideas, I haven’t tried out the “Nullables” concept myself but find it interesting and might solve some test headaches: https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks
guys, in my internship, the higher ups want me to use AI ML in testing APIs
one of the seniors suggested to use OpenAI models, if i can
is this possible?
I am newbie into the testing world, It would mean a lot if someone could give their views on this
API testing is a broad term to apply AI or ML,
so in what part of API testing can AI ML be applied and do you have any clue to that?
Thanks!
when you are asked to do things you don't understand during an internship, you must ask them to explain/clarify. if you don't ask, they will assume you underestand.
I've hired over a dozen interns over the last few years and this is, BY FAR, the most annoying thing in managing them.
90% are afraid to ask questions. Your mentors/bosses do not know what you know or don't know.
I did ask them to explain, the MD just told me some info abt supervised learning, neural networks and training dataset.
if you still don't understand, you need to ask them to rephrase
or be clearer about what you don't understand
etc, etc
I understand it's hard to get over the "I don't want to appear stupid" feeling. but you REALLY need to get over it. it's critically important. it's how you reach excellence
The MD said that he told what all he knew
My mentor, who is another person, has no idea on this as he works in web dev team
I agree to this
he did not understand your question
my advice is this: start from the end. i.e. ask him what the objective is, what the the final work product should look like/do. i.e. how do you know if you've been successful or not?
because, I suspect that is where you are confuzelled. amirite?
I did ask this, and the MD guy said when an endpoint is given to ur Model, it should be able to generate test cases and expected response
And then make requests and verify them
oh, ok. that seems clear enough
most can't. GPT-3.5 and GPT-4.0 can
For resouces whose ids and existence are unknown to it
well, you'd have to feed it the signature and docs
Even they are failing to give proper test cases
and perhaps provide some clarification
That might be chaotic, cuz some API might have those cases possible but for some other APIs those cases might not hold
you're not really tuning the model here, the model is already set. you're feeding it inputs
but whatever
yes, it can make mistakes
Hello 👋
With FastsApi I would need to override a dependency injected into the Path operation decorator. I found this https://github.com/tiangolo/fastapi/discussions/6479, but can't get the patch to work. anyone have any idea if there is an easier way to override this dependency?
Thx
How to pass auth argument in responses.add while mocking, do you guys know any matcher
below is not working
responses.post('https://pretialast/api/tcs/v1/user-auth/login',match[matchers.request_kwargs_matcher({'auth':requests.auth.HTTPBasicAuth(username="test", password="test@123")})],json=resp_dict,status=200)
hi
how are you guys doin?
e
awhy no one is talkin?
or chatting?
due
thats weirds
I work on large language models, and this sounds like uninformed hype to me. Try https://github.com/schemathesis/schemathesis for auto-generated API tests.
(disclosure: I also co-wrote the paper on Schemathesis)
I'm struggling to think of unit tests that would be useful for a sorting algorithm
I have one that tests whether or not it will give a properly sorted array but that's it
For this type of algorithm, testing cases that are "sparse" or "most extreme" is sometimes helpful. So I would suggest some inputs that are entirely sorted, except that two entries are swapped; possibly also an input that's entirely sorted except for one stretch somewhere; and also an input that's reverse sorted.
I see, that's very useful thanks!
holy shit this is exactly what i needed, how did i miss this
though, can I mock graphql responses with this library?
I'm trying to "mock" a graphql server and it's responses within my unit tests -- the data is not important as I can easily just test the type/schema of the response and not the actual data inside but i'm trying to avoid spinning an external server as that would slow my testing down
No, it's a tool for testing APIs, which is pretty different from pretending to be the API. It does support generating GraphQL queries (etc) though!
Is it common practice to unit test terraform code? If so, which frameworks are best?
Can someone tell me why my server is rejecting hashlib??
If it is provider code then yes, if it's project code then you usually write infra tests instead that check if code deployed == code defined, especially permission policies
Any e2e framework with support for AWS SDK can do that
Did you solve your issue? If not I can give you example of properly overriding settings. The trick is to wrap your app inside function
Why do you want to mock it? Is it a 3rd party service?
so i can test my api calls and graphql lol
Empty list. Just one item. Those are often cases people miss :P But there's also hypothesis and mutmut if you want to do proper testing.
Made a pretty simple 2D rendering app, but tried to support as much as possible, feedback? https://paste.pythondiscord.com/tocijobedi
But is it a 3rd party service? If it's yours API then you don't need to mock it
i see no questions https://kodare.net/2021/05/19/how_to_ask_for_help.html
Ask something specific Before asking for help, try to make the smallest example you can of the problem. Don’t just show us your entire code base. If you don’t understand the advice given, say so!. Don’t just ignore it. Don’t tell us error messages in your own words. Copy paste them. In full. “Doesn’t work” is not an error message. How does it no...
hi guys, can someone help me with this unit testing
There is a code(which is not allowed to change anything) and there is my solution to it, can you please check the possible mistakes that i made in the unit testing code
this is the code(with class Robot) - https://pastebin.com/pLcs1AeQ
this is unit testing code- https://pastebin.com/2nwFz9WU
good enough to me. plentifully overtested code.
further improvements can be made only with changing Robot class code ^_^
there is of course room to improve its further
but that is certainly beyond set task and requires preferably helper third party libs to be installed
Can someone tell me how I need to structure my repo so that calling pytest from root will work?
https://github.com/baskuit/R-NaD/tree/comments
I have /tests in my root dir with test_etc.py, everything folder has an __init__.py.
user@pc:~/Desktop/r-nad/tests$ pytest
========================= test session starts =========================
platform linux -- Python 3.10.7, pytest-7.3.1, pluggy-1.0.0
rootdir: /home/user/Desktop/r-nad/tests
collected 0 items / 1 error
=============================== ERRORS ================================
__________________ ERROR collecting test_nashconv.py __________________
ImportError while importing test module '/home/user/Desktop/r-nad/tests/test_nashconv.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.10/importlib/__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test_nashconv.py:3: in <module>
from ..environment.tree import Tree
E ImportError: attempted relative import beyond top-level package
======================= short test summary info =======================
ERROR test_nashconv.py
!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!
========================== 1 error in 1.06s ===========================```
does python -m pytest do what you want?
no, I still get the exact same error
Will adding pytest test paths help? https://docs.pytest.org/en/stable/reference/customize.html
ah i just fixed it. running as module worked but I had import .. still in there
ah, my bad, I didn't read the full thing. Yea, you are confused about how imports work in python. They look like relative paths, but they are very much not.
You probably want something like from environment.tree import .... I don't like the package names environment, util and learn in the top level like that personally. It's a bit conflict-begging
interesting. shame since I'd prefer to keep it very simple. Its not intended to be installed via pip or anything, I just prefer folders for organization vs just letting everything sit in root
I mean.. just one folder more with a project name isn't much different no? Anyway, you can still do it the way you have now. No problem.
You just need to get the imports right
quick question, how would you build a unit test to test that a class quand find and read a specific config file in it's constructor?
"quand"?
Ask one question at a time and people can help
how can i fix this error
pip -m pytest --version
There should be a C:\Python311\Scripts folder where the executables are generated. That should be in your PATH, not site-packages
That or use py -m pytest
better use pipx for clis
@proper wind @proper wind
Do you guys know any Discord server that can help me?
My first account is not here becouse its sweden.
My first account[That Hi Guy] From sweden go baned by sweden cyber security for random reasons
My secound account [That Hi Gay] Made in Iran becouse i got deported to Afghanistan from sweden.
("I just want to ask")
[Can i join you guys to learn code?]
#I_AM_NOT_GOOD_AT_PROGRAMING!
I am from Afghanistan & My jobb is :
Nothing / Student
I can speak :
Persian , Dari , Tajik , English , Greek , Swedish , Danish & German.
My Hobby is :
Coding
My life is :
Trash
My favorit food is :
I ead evrything!
@proper wind Becouse i want to join & learn!
Nope!
Nope
I have girl firend!
I do!
I was in all of this country more than 2 years!
@proper wind سلام من میخوام به شما بپیوندم من اصلا گی هستم من میخوام کد یاد بگیرم !
کمک میکنی یا نه ؟
@proper wind Hallo das bist nich gut!
@proper wind 😦
why not write it in Finglish
ok
I do!
Unmute me and talk to me!
HAHAH!
Kesafat!
@proper wind How to varify voice?
@proper wind How to open this button?
@celest pilot How to unmute my self?
Y'all might be looking for #voice-chat-text-0 .
Hi,
can someone provide me some assistance with fixing my test_db?
I got this
@pytest.fixture(scope='session')
def test_app():
app = create_app('tests.settings', validate_response=True)
ctx = app.app_context()
ctx.push()
yield app
ctx.pop()
@pytest.fixture(scope='session')
def test_db_schema(test_app):
"""A database for the tests."""
db.app = test_app
with test_app.app_context():
db.create_all()
yield db
# Explicitly close DB connection
db.session.close()
db.drop_all()
@pytest.fixture(scope='session')
def _db(test_app):
"""Provide the transactional fixtures with access to the database via a Flask-SQLAlchemy database connection."""
return db
@pytest.fixture(scope='function')
def test_db(test_db_schema, db_session):
pass
When I try saving a batch of data created with factory-boy
def save(self) -> M:
db.session.add(self)
try:
db.session.commit()
except IntegrityError as sql_exception:
logger.exception(sql_exception)
db.session.rollback()
raise APIException(detail='Unable to save to DB') from sql_exception
return self
I get error 'psycopg2.errors.UndefinedTable'
None of my models is being created to my test DB.
It's not an IntegrityError what I am trying to catch as I don't get my expected error message. As far as I can interpret the massive stack trace, it turns in to a FlushError at some point... Really clueless waht to do with this
At first glance it looks like different fixtures use different app contexts
If you use a in memory DB, then it's not a surprise it's gone
gm
@chilly knoll You've sent the same message in several channels. Could I know what you're trying to do?
Hi, is there a way to skip a pytest test based on a condition that involves a fixture?
you can call pytest.skip() in the body of your test, and base it on any condition you want.
Right, sorry I forgot to add that I want that to be a decorator
And I think that using a fixture inside of a decorator won't work
There's probably a way to have access to the fixture, but I don't know it off the top of my head. What does the fixture do? Can you link us to some code?
Can anyone raise a Pull request with unit tests for this open source github repo?
https://github.com/Adnan-Jindani/cryptoPlay
Yea
The code currently isn't easy to unit test because the whole code executes an an import side effect. You should move all of that to functions using https://docs.python.org/3/library/__main__.html#name-main then unit tests can import individual functions and test them
pytest question: if I have two "class" scoped autouse fixtures, but one is declared as a global function and the other is declared as a test class method, is there any ordering defined between them?
@pytest.fixture(scope="class")
def order():
return []
@pytest.fixture(scope="class", autouse=True)
def fixture1(order):
order.append('fixture1')
class TestFoo:
@pytest.fixture(scope="class", autouse=True)
def fixture2(self, order):
order.append('fixture2')
def test_order(self, order):
assert order == ['fixture1', 'fixture2']
This test passes for me, is this order guaranteed?
the docs say that there isn't a defined ordering between autouse fixtures of the same scope, but scope here refers to the "scope" keyword, not class vs. global scope
is it? this is pretty similar to an example from the docs: https://docs.pytest.org/en/latest/how-to/fixtures.html#running-multiple-assert-statements-safely
Mutating a fixture like that is pretty evil imo. Will make it really difficult to follow the code.
according to the docs, that's a feature
idk though, I only learned how to use fixtures yesterday
I mean, mutation that isn't local is pretty evil itself. Imo you really don't want your tests to be hard to understand and debug. That will make your life miserable :P
Can I DM?
Thanks for the help @hexed cloak !! 👍
no. We ask in the open so everyone can contribute and learn
Okay
Same reason we have patents actually. Publish in the open instead of keeping secrets.
Patents? for pyhton?
In general
Oh, okay
Can you give us a PR with unit test added please?
Hi. I'm trying to test an init function
Do I need to have a setup and tearDown methods
You'll need to fix your code so it is unit testable first
No that's optional
Hello, I come up with a general question, any advices or thoughts I have to have in mind to break software? (E.g push my own software to the limit)
not really understood the question
did he mean code architecture, or performance quality (of desktop part? of server part?), or testing for edge cases, or having good coverage or smth else
I develop mostly back-end, fetching api's/scraping parts
Having good coverage in any of that or which thoughts do I have in my mind to find Bugs easily
use static typing ^_^ (gradual typing in python case https://careers.wolt.com/en/blog/tech/professional-grade-mypy-configuration )
write unit tests with coverage metrics tracking for more than 80% of your code
have CI running and enforcing it automatically
that alone will make a difference already
And sometimes I have problems testings some scraping projects when they return me a Big json response.
Some scripts paginate over 30 documents in 500 pages and imagine that there is an error in the document 27 and page 259. (Some item fields not coming as expected)
How do I test that? Mocking the json?
I mean, save a sample response of the requests i make in json files and making unit tests on these responses?
static typing with structs again the answer. (using library pydantic)
class ParsedData(BaseModel):
field1: str
field2: int
nested_objects: List[BaseModels]
parse data to structs. use them in your code with mocking
Have integration tests checking that JSON files downloaded from real stuff are still fitting the structs.
Run unit tests quickly during development
Run integration tests at least with CI or smth. mocking them or not, depends on how easy to obtain JSON all the time for you, how much it is fragile. it can be mocked too. but it will break only tests that transform JSON to BaseModel
Thanks man 💪🏽
Ill try It out
!rule 5 also, web scrapping is bad without owner's permission, mkay ^_^
https://media.tenor.com/5q1Ly0am-MAAAAAC/mmmkay-mr-mackey.gif
5. Do not provide or request help on projects that may violate terms of service, or that may be deemed inappropriate, malicious, or illegal.
#web-development message that guy wrote good answer why
P.S. in your case you would benefit greatly, from having integration tests running in cron job every day btw (Github Actions have support for this feature)
since in this way they will tell you automatically the day, when your code is no longer fitting jsons downloaded
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
yes, I try to read the terms and conditions to check if It could be legal
perfect
Yeah I'll try to do that with the documentation link you provided 👍
Hey, so i have a tool that has 8 textfields. I can give the option to open a PDF file per dialog and it will extract stuff from the PDF following a regex schema. So far it is working with 2 files, but i want to write tests to make it work with even more PDFs without me testing on each one independently.
The strings that are extracted from the PDF will be written into a list containing tuples of strings and integers. My approach would be to somehow load the pdfs after another, create multiple lists with the results available and compare the extracted lists with the pre defined ones, but i'm still clueless on how to approach. Screenshot shows how it looks inside the tool.
The method on how the list is filled is:
path = self.open_file_dialog()
formatted_krits = auto_pdf.krit_list(path)
i = 0
for x in formatted_krits:
self.krit[i].setText(x[0]) # list that i want to test
self.krit_von[i].setText(x[1])
i += 1
👋
I wanna know a bit about unit testing. What is it used for and how can it help me? And, where can I learn unit testing?
read book
It answers exactly your questions
" What is it used for and how can it help me? And, where can I learn unit testing?"
it explains meaning behind it, its history, and paths to learn
learn after that more practical head on approach in TDD by Kent beck
Ok thanks
Guys how can I test my python library https://GitHub.com/NaviTheCoderboi/NewsDash using pytest?
classic problem and solutions
- creating a Spy of NewDash client, that reads maximum raw files of html bodies/json bodies received from real NewDash.
- Your other code is tested to interact with this Spy as expected, parsing data, rendering results, asserting expected stuff to see.
This was unit testing section
in addition having few pytest tests, marked as @pytest.mark.regenerating?
by default aren't runnable. though in CI probably should at some point
They will download new version of JSON bodies/HTML returns from NewDash, that will be caught by your NewDash spy for the rest of tests
====
in this way during local development => you have fast predictable unit tests that are fully local and aren't needing to interact with NewDash. fast and easy to debug.
if u have CI running that runs both Unit tests and Integration(first regenerating then running your unit tests, which can be done in same pytest fixture that was reading saved JSONs before)
You will have running integration tests to validate code being valid too
optionally for full solution, since your solution involves parsing and main meaning of it => CI integration tests should be launched as CRON job to run repeatedly, once in a while checking your code as still being valid
See this book for more explanations, this stuff is explained regarding Spies too there
Last, but not least, make sure when your Spy yields parsed data to other unit tests, it is maximum type hint enforced one by mypy and data transfer objects (DTO), which is nice to be Pydantic BaseModels, are using all the time maximum... precise values (No dictionaries!!). Only nested Pydantic BaseModels, and simple types like strings, integers, floats, datetime. Even those ones should be further typed by from typing import NewType, to decrease confusion spreaded by having too many values of same simple type)
then your other tests will not depend on changable / dynamic / unknown reliably implementation details of NewDash
but it will depend on your own fully controlled and secured conversion of NewDash data into your own application code data
xD that is how your unit testing NewDashSpy should be looking. the wall, that allows no untyped third party data structures into the rest of your city(code), until it was fully converted into legit citizen of a city
https://careers.wolt.com/en/blog/tech/professional-grade-mypy-configuration
https://docs.pydantic.dev/latest/usage/models/
https://docs.python.org/3/library/typing.html
https://docs.pytest.org/en/7.1.x/contents.html
https://mypy.readthedocs.io/en/stable/
all those documentation you will eventually desire to read, if u want maximum quality code
if for some reason your requirements wish to be not using Pydantic, so that users of library would not be forced to use it... ergh, u could avoid its usage by using regular python Dataclasses, but i would not recommend it.
Pydantic solves a lot of problems out of a box, including OpenAPI data generation and serialization and deserialization and etc. Library advantages of it, too huge to be not adding.
mypy / pytest are libs that aren't needed distributed to user since they are for your dev env / CI env / testing env only
I had a discussion about unit testing in #career-advice . I just don't see how I can unit test this if it's rendering exactly how I want to.
import React, { useState } from 'react';
import axios from "axios";
import './App.css';
function App() {
// new line start
const [profileData, setProfileData] = useState(null)
function getData() {
axios({
method: "GET",
url: "/profile",
}).then((response) => {
const res = response.data
setProfileData(({
profiles: res.profiles
}))
}).catch((error) => {
if (error.response) {
console.log(error.reponse)
console.log(error.response.status)
console.log(error.response.headers)
}
})
}
function profileList() {
const pList = profileData.profiles.map(( profile, i) =>
<p>
<ul key={i}>
<li>{profile.name}</li>
<li>{profile.about}</li>
<li><img src={profile.image} width="250px" height="250px" alt={profile.name}></img></li>
</ul>
</p>
);
return <ul>{pList}</ul>
}
console.log(profileData)
return (
<div className="App">
<header className="App-header">
<p>To get the profile details: </p><button onClick={getData}>Click me</button>
{profileData && <div>
{profileList()}
</div>
}
</header>
</div>
);
}
export default App;
This is a dumb test isn't it, because the system running this test can only test one of these cases?
class TestCheckOutput:
def test_not_windows(self):
if platform.system() != 'Windows':
output = check_output(['ls'])
assert output != ''
def test_windows(self):
if platform.system() == 'Windows':
output = check_output(['dir'])
assert output != ''
def check_output(cmd: List[str]):
return subprocess.check_output(cmd).decode().strip()
testing is too hard. My tests pass alone but not together.
This is why I never write tests because if I did my entire life would be writing tests.
and nothing would ever happen
you could change those 2 tests into 1, and conditionally use either ls or dir
depending on the system
tho I'm not sure what the point of those tests are
check_output is used to read the output of a subprocess and it needs to work. lol
or like....
is that a situation where I'm not even testing my own code, I'm running a test on a wrapper for subprocess.check_output()
yeah okay there is no point for that test I guess.
The bigger problem I have is that much more complicated tests are breaking each other but pass alone
I thought thewhole point of using the testing framework was to run the tests in isolation
honestly, these tests are a waste of my time lol. I'm just deleting them.
yea I thought they seemed excessive since the code you're testing looks like a really thin wrapper around a stdlib method
and I guess it depends on what you're testing that is causing the tests to interfere with one another
might need a pytest plugin to mock some things possibly
yeah... I took a break and Im less frusterated. I think I am trying to learn testing by writing tests for things that are too complicated for my understanding of the library and testing in general. I've decided to focus on less complicated things but things that still are useful to test.
I decided to eliminate that wrapper function. I think when I started writing the function I didn't expect it to be such a simple thing.
Anybody?
if you don't own backend from which you query data... better making test, you receive expected data from it ^_^
in general i would say... 50%+ of frontend unit testing can be solved not by unit tests, but by just using typescript
it will kind of automatically catch more than half of cases for which frontend is expected to be tested
shrugs. so in conclusion you can test your code in next strategies
- You receive expected data from backend (highly preferably doing it with typescript in addition) (this is kind of integration test, checking that your backend depdency is behaving in expected way)
- you can make test that checks, if page is rendered -> and some simple phrase is present (very simple test)
- you can make test that interacts with React testing API, loads this component, clicks the button, and asserts that expected data is present (This can be made pure unit test, if you will mock here data from backend (again better doing it with typescript, otherwise does not make sense a lot)
test #2 can be erased when you made test #3, since it repeats test #3. well, or u can just extend test #2 into test #3
i would say, yes. silly test. you should be having single same test for windows and linux
it just should be using function that yields different result based on it being Windows or Linux
then just run tests twice, once in Windows, once in Linux (in CI, in github actions for example). Github Actions can be do it in Matrix for both OSes with same code
I see.
ergh, just learn typescript. you are frontender, it will be already big improvement of your code quality and life. (type script kind of replaces half of tests for you)
Unit testing is harder to get in frontend due to your environment being way more heavily polluted with framework than for other devs. (Frontend frameworks enforce their own hard to unit test code logic)
You probably need more intensive backend experience first, before u will get how to test frontend code
um, I'm not testing frontend code. It's not a web application at all actually.
oh, sorry, mistook you on second rereading after some time with that guy above you
ohhh it happens
skip my last msg about frontend
I have another question related to pytest...
sure.
class LocateRetroarchConfigDir:
# Passes
def test_found_from_nonexisting_path_in_config(self):
config_dir = locate_retroarch_config_dir('')
assert config_dir == "dsfdsfdfs"
# Fails
def test_found_from_nonexisting_path_in_config():
config_dir = locate_retroarch_config_dir('')
assert config_dir == "dsfdsfddsfds"
Both of these should fail. Why?
function name locate_retroarch_config_dir is not telling me enough meaning of it
test names aren't giving me enough meaning either to understand what your code does
insufficient information about code application logic
the question related to the fact that they are the exact same test, one is a method of a class and one is a function. Additional context for that problem shouldnt be needed. Theyre the same test.
oh, so your problem, you are receiving different test output?
the only thing i can think to do is just go back to using functions because the classes are giving me passes even when i intentionally make them fail
sure, they should be receiving same output, both should fail or pass
if it is not happening => u are having some kind of bug i guess ^_^
when i grouped tests into classes for pytest, it worked fine for me
nothing changed
yeah I dont really understand because it seems to work in other classes. but it's making me not trust the results.
look
class LocateRetroarchConfigDir:
def true_is_false(self):
assert True == False
$ pytest tests/
=============================================== test session starts ================================================
platform linux -- Python 3.10.6, pytest-7.3.1, pluggy-1.0.0
rootdir: /mnt/hdd/hacks/smwc-scraper
collected 6 items
tests/test_utils.py ...... [100%]
================================================ 6 passed in 0.05s =================================================
the beauty of tests -> even if you screwed them up, they still work correctly from the point of showing errors ^_^
Oh, i underthan why
you aren't using conventional name for Test class name, for this reason test is never discovered in class
if i remember correctly Pytest uses Unittest convention for it
TestXXXXX is expected name
Just revisited one of my old projects. This is the back-end code for it that contains JSON data.
from flask import Flask, url_for
api = Flask(__name__)
@api.route('/profile')
def my_profile():
response_body = {
"profiles": [{
{
"id" : "4",
"name": "Madara Uchiha",
"about": "was the legendary leader of the Uchiha Clan. He founded Konohagakure alongside his childhood friend and rival, Hashirama Senju, with the intention of bringing about an era of peace. When the two couldn't agree on how to achieve that peace, they fought for control of the village, a conflict which ended in Madara's death. Madara.",
"image": "/static/madara.jpeg",
}]
}
return response_body
with api.test_request_context():
print(url_for('my_profile'))
I actually wrote a test case for this. How is this for testing?
how do you mock a binary file that when executed with binaryfile --version will output th1s 15 4 t35t. I could create a binary file, write some bytes to it, and then pass it to subprocess.check_output.... but it would just give me an OSError because it wouldn't be a real executable.
def get_bin(path: str,
which_cmd_name: str,
version_output_substrings: List[str]) -> Path:
def run_which() -> Path:
if platform.system() != 'Windows':
try:
path = subprocess.check_output(
['which', which_cmd_name]
).decode().strip()
return Path(path)
except (subprocess.CalledProcessError,
PermissionError) as e:
print(f"{which_cmd_name} is not installed")
return ''
if path:
bin_path = Path(path)
else:
return run_which()
if bin_path.exists():
try:
# any(substring in string for substring in substrings)
version_output = subprocess.check_output(
[bin_path, '--version']
).decode().strip().lower()
if any(substr in version_output for substr in version_output_substrings):
print("Path in config.py is valid")
return bin_path
else:
print(f"This is something other than {which_cmd_name}")
except (subprocess.CalledProcessError,
PermissionError) as e:
return run_which()
else:
return run_which()
This is what I want to test.
you use it like this
flips_bin = get_bin(
FLIPS_BIN, # This is a user supplied path to a binary that may or may not be valid
which_cmd_name='flips', # This is the command where the binary can typically be found if installed to PATH
version_output_substrings=['floating', 'flips'] # These are substrings found in the output of `flips --version` that confirm its flips.
)
I have no idea where to begin testing
this is the best I have
class TestGetBin:
def test_found_from_blank_path_in_config(self):
bin_path = get_bin('', 'bash', ['GNU bash'])
assert bin_path.exists()
def test_found_from_nonexisting_path_in_config(self):
bin_path = get_bin('/does/not/exist', 'bash', ['GNU bash'])
assert bin_path.exists()
def test_found_from_existing_path_in_config(self):
bin_path = get_bin('/bin/bash', 'bash', ['bash'])
assert bin_path.exists() and str(bin_path) == '/bin/bash'
test case is not found.
plus using dictionaries of data is kind of bad too. use Structs of pydantic base models ^_^
with api.test_request_context():
print(url_for('my_profile'))
How is this not a test case?
well, it is not executed separately from working code of application, therefore it is not test case
plus using dictionaries of data is kind of bad too.
How? From my understanding, the Flask library turns the dictionary into JSON I believe?
usually working application launching and test launch are different entrypoints of applications
oh ok
sure. but using just dictionaries is bad ^_^ use pydantic base models, they are typed structs (can be automatically transformed into dictionary or json for output)
Never heard of pydantic base models. I'll look into it.
I have a really crazy idea. I was thinking about... I don't really want to send unnecessary requests to test my scraper, so instead I saved a copy of the html that the server sends to github, and in the test, and I use that instead of the real server. You could argue that if what server sends is different then the tests cant be trusted but... in reality that is the eventuality of any scraping tool anyway. So doing it this way just reduced the requests used to test.
Testing a scraper is an interesting situation, but generally what you did is for the best. If your test relies on an external server, it can go down unexpectedly which means intermittent failures for your tests
Can you provide me a resource on how to write test cases for back-end code?
That is completely correct.
I would recommend in addition making pytest optionally regenerating saved HTMLs automatically as part of your test code
@rigid ridge just above answered with more details about how to go best
Basic flask examples with pytest
https://flask.palletsprojects.com/en/2.3.x/testing/
If u will start using sqlalchemy, see here to simplify tests
https://factoryboy.readthedocs.io/en/stable/orms.html
Otherwise read how to use pytest
https://docs.pytest.org/en/7.1.x/contents.html
But how to test from theoretical and practical approach?
Theory will answer book
Best principles and practices by Khorikov
How to write unit tests from practical theoretical approach, answers book
TDD by Kent Beck
Thanks a lot! I'm reading the first documentation
import pytest
from my_project import create_app
This is an excerpt of code written in it. I don't understand the parameters [my_project] and [create_app]
is my_project the name of a folder or file?
then it is too early for you to jump to tests
https://flask.palletsprojects.com/en/2.3.x/quickstart/
https://flask.palletsprojects.com/en/2.3.x/tutorial/
read all flask features from quickstart to different tutorial contents. It shoudl be all explained.. at least in some first chapters of tutorial
oh yes, their factory pattern create_app is
https://flask.palletsprojects.com/en/2.3.x/tutorial/factory/
as for my_project, that requires you understanding of basic Python language features, how its import/module/packaging system works
absolute and relative importing including
it includes you to learn preferably, how to organize python files/modules into folders/modules/packages, without doing PYTHONPATH hacks.
optionally you can skip learning all this stuff and just using Django. ergh, it boilerplates everything for you, including application structure
at some point you will still need learning such basics
and it is possible to mess up Django greatly beyond salvation too, if u make too mad code
as for my_project, that requires you understanding of basic Python language features, how its import/module/packaging system works
Ok so it's for files then. Not folders.
technically both
let me try explain some simple examples
~/ lets asssume is an address of your root folder of a projects
~/my_project.py file can be containing code that you can import as from my_project import create_app
assuming you will have python launching the code from same level?
so, python is allowed launching your code in this way to work correctly python3 my_project, python3 my_project.main, python3 -m my_project, gunicorn my_project.main
as long as u launching code in this ways, python will discover automatically absolute imported files and folders of code from ~/ root of your project. (Because you launch with absolute path starting from ~/ root of your project)
your code can be located in
~/app/my_project.py and it can be imported as from app.my_project import create_app, and possible to launch as python3 -m app, or python3 -m app.my_project or gunicorn app.wsgi, it will work both fine then
ergh, it is about getting how python importing works
your files like my_project.py can be put into folders of code like app
as long as app folder has __init__.py at least as empty file, it can be having additional code of files like my_project.py
um, probably not very understandably explained, read somewhere how python absolue/relative importing and packaging works, that mentions all the things i mentioned
TLDR: as long as you launch python application with telling path for launch from the root of your project folder, it will behave correctly in discovering your code in absolute import parts from the root of your folder. that's important
(You can also use relative imports to help you in some cases)
Just to simplify things, You said to run test cases that a py file has to be separate from the file that I am trying to test right? So somehow the test.py code has to access the base.py file somehow in order to test the code in base.py. That's comes with importing. So I would have to write something like
import pytest from base
right?
yes, it is assumed you have for example base.py as your working code
and all test files are explicitely tests.py or test_somename.py... at least according to generic rules of how python programms are usually structured
your test in tests.py wil lbe importing from base.py right and having written smth like
from base import create_app
def test_abc_route_works():
app = create_app()
resp = app.get("/abc")
assert "123" in resp.content
tests will be automatically discovered by pytest during pytest command invocation
[pytest]
python_files = tests.py test_*.py *_tests.py
if you will have in root of your project file pytest.ini
it will set the rules how tests are discovered
no, this will not work. re read flask documentation
https://flask.palletsprojects.com/en/2.3.x/tutorial/factory/
https://flask.palletsprojects.com/en/2.3.x/testing/
specificcally those two sections. you are supposed to import app creating function (in your case api)
I believe that my base.py code does not have an app creating function so it's a little confusing.
from flask import Flask, url_for
api = Flask(__name__)
@api.route('/profile')
def my_profile():
response_body = {
"profiles": [{
{
"id" : "4",
"name": "Madara Uchiha",
"about": "was the legendary leader of the Uchiha Clan. He founded Konohagakure alongside his childhood friend and rival, Hashirama Senju, with the intention of bringing about an era of peace. When the two couldn't agree on how to achieve that peace, they fought for control of the village, a conflict which ended in Madara's death. Madara.",
"image": "/static/madara.jpeg",
}]
}
return response_body
with api.test_request_context():
print(url_for('my_profile'))
My back-end is proxied in package.json so that's how I get the back-end running
{
"name": "fullstack-flask-react",
"version": "0.1.0",
"private": true,
"proxy": "http://127.0.0.1:5000/",
So the example in
flaskr/__init__.py
import os
from flask import Flask
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
Isn't what I use.
It's best to convert your code to use a blueprint and app creating function it's easier to test that way
too early for this refactorization. the guy needs just to setup in any way testing first.
first time python has its own challenges
Hey. I was having trouble on how to make a test case for my code so I asked ChatGPT and they came up with this.
I wouldn't trust ChatGPT with code as usually all the programs either don't work the way they are supposed to or don't work at all
Instead you can tweak the code it generates to get the output you want
Or they are just copy paste from some test that was part of the training set 🤣
Code license laundering 😆
Hi, everyone! I'm getting hired for a QA position, and I'll be using Python. Do you guys have any suggestion as to what I could be learning to "hit the ground running"?
I've never really done testing with Python. I've been looking into Selenium so I can learn it a bit (Selenium will be used on the job).
Perhaps any Python modules that help with testing? Thank you in advance!
pytest is the most commonly used testing framework in Python, so you should look into that. (It is compatible with unittest which is part of the standard library.)
!pip pytest
I'll look into this. Thank you!
I believe you can write Selenium tests on top of that
Personally I also use hypothesis for property-based testing, but that may be more suitable for directly testing frontend/backend code rather than browser-based testing
My boss mentioned that he wants me to become full-stack eventually. I believe this should help me with that route?
yeah, you should take a look into that library
it makes you think differently about how to structure your tests
If you can possibly avoid Selenium you should. It's super slow. Most of the time you can get away with just bs4.
I am similarly new to TDD approach, and I have found a playlist where you walk through a coding project. I'm about halfway through so far, and have really appreciated it: https://www.youtube.com/playlist?list=PLVWk3kKbCAAuPPr_eh4KNKdL2hDSNFH3H
how do you make unit test for scripts where it needs sudo commands and opens system files that are root?
by definition anything that needs sudo can under no circumstance be a "unit"
the integration tests would open random other files in a per test tmpdir and do the deeds
unittests for the functionality wouldnt open files
thanks! gotcha so I'm thinking the "unit" is the parsing of the strings taken from the file?
I tried pyfakefs and it works mostly for non-system files
for example - the terms unit/integration/e2e are a bit washed up these days, but one can meke some pretty clear cases between "functions that do stuff without those perky side-effects" vs "functions that interact with the world" vs "taking all of the world for a spin" (+- some logging ;P)
wow cool terms
that depends on the definition of unit testing u use @restive bay
in strict strongest case, yes, it would be impossible to have it unit test
well... in some more light definition, we can still make it as local unit test (bordering integration testing)
if we use docker containers to test this functionality
whole functionality can be easily tested within same CI pipeline without external resources
begone, terminology bullshit games are waste of time
if it spanns processes, its not a unit, in any way even close resembling the initial definitions
hey you have more articles or books I can read about this?
and redefinging everything until it means anything is just dishonest
anyway => with CI and containers => and u still own fully the environment / application / infra related part of code for it, it is still unit testing to me 😛 or at least unit testish integration.
at least we can agree hopefully, it remains local testing without uncontrolled remote dependecies 😛
still.. files can just be strings returned by functions right?
files/folders whatever their owners are
lets use the termin... at least it is locally testable functionality ^_^ in a way that test runs can be isolated in a good way from each other. and that's what is important. (repeated test runs do not pollute test results of next test runs)
more context neeeded, given that your full system includes sudo being specific is important
hmm right, I guess when the command starts with sudo python -m unittest
meaningless term as any developer friendly laptop can basically pretend to be a cluster these days
btw, why would you need sudo to test your functionality in the first place
it's not a requirement but an option
what stops you from running tests as python3 -m unittest ^_^
is it even needed at all option? does it bring some extra functionality
its intensely recommended never to need sudo or root to run a testsuite of most sizes
or at least not designing your application in the way they need sudo at all
kind of messy to do that if that is not necessary for its working / functionality
ok gotcha intensely not using sudo for sure
for context the system files are log files
its like - there are cases - but so far in all of those cases the dev is having a strong drink and asking themselfes why they couldn't avoid that
so have a extra group for them that allows access and have the service run as that group
that's not unit testing though?
giving root for log file reading is pretty much a malpractice - use groups and prermissions no need for root ever
agreed. though that's out of my scope
maybe im just a fucking dumbass, but testing seems completely unnecessary to me.
the concept of having so many files just to test your fucking program when you could just enter in the values yourself seems ludicrous. and at that point, why even do the testing at all? you know what values will fail
well, computer programs exist to help us do stuff in a fraction of the time we would spend doing it by hand, so why not have programs to help us test other programs? then you can make changes to your program and run a single command to know if you accidentally broke a dozen other features
though frankly im terrible at writing tests, ive got a couple packages that id like better coverage but i dont know how to test them due to their I/O and side effects (or maybe im too lazy to figure it out)
at what level of complexity do you see it as a reasonably persuit to start adapting a code base for testing, the overhead in the codebase always felt rough to me vs having some external test program that called on the functions and tested against which left the source effectively clean?
or do I have things flipped and that is a valid use case?
Oh it's meant to test already existing functionality, not test if a new addition works
same point applies, those tests will be there to warn you of new bugs and regressions in existing code as the codebase evolves
Sometimes you make an innocuous change to your code, one which is obviously correct and couldn't possibly cause problems, and then something unexpected breaks. If you haven't done this, then you haven't been coding long enough. This is what testing existing functionality is for.
also note that there is a difference between a random one off one can code together in half a hour and never change and something that is large, multi months effort customer facing, changed over years by different people of different skills
it can seem low value to add tests to the immutable one off
its typically always saving ones ass to add tests to the longer term thing that will change by many
also a fun caveat, the one-off can often accidentally turn into something permanent that will change over time, and its typically very hard to test something thats throw away and anti repair ^^
so adding tests and striving to make things easy to test tends to have delay payouts and wins
Unit testing is not even near comparable to software testing
@hollow galleon the keyword to focus on is 'unit' the smallest possible code that you can test
unit testing is a subset of software testing
Unit testing something people do to see if something works. As simple as that
Continuing: TDD is a workflow for unit testing. A nice side effect of it is tested software, but the workflow is more about designing code in a step-by-step approach.
Sort of makes sense to change the title of this room to software testing
Ok so totally new at TDD and I've backed myself into a corner. So say I need to got to an ftp server and get a csv file. I'm not ready to code out a mock for the ftp module I'm importing because it's pysftp and well maintained, so I test for the presence of the file in my cwd. I've now created the function to grab the file, but unless I run the code (or move a file over) I can't see how I get my assertion to come true. What am I missing?
I would wrap the ftp request code in a function and I would mock that function returning success and failed responses
Now to read up on mocking. I appreciate the advice, thanks!
Depending on importance of the service, i would have written integration test
That raises docker container via docker compose or raises GitHub Actions service with ftp server and would try to get my file out of it in integration test
Unit tests for the rest of program would just mock it and grabbed file locally without using ftp
I haven't gotten to integration testing yet, but super cool you can do that!
Hey all, happy monday.
Curious about testing this scenario:
I have code that returns a JWT from our Azure AD instance using the msal library. It gets this JWT by:
-
instantiating an object of msal.ConfidentialClientApplication and passing 3 args to the constructor: a client ID (string), our Azure AD instance endpoint (string), and our Azure AD client credential (string).
-
calling a method of this object (acquire_token_silent) and passing in the 'scope' of the Azure AD instance (string) and the account (None).
-
if 2) fails, call another method (acquire_token_for_client) and pass in only the scope.
-
return the JWT that is in the response from Azure AD.
As you can see, the main functionality is from the msal library, all I do is give it the various string arguments which are environment variables that are gotten by os.getenv.
What is the proper approach to testing this? I essentially didn't write any code, just making calls to methods that other people wrote. Is this something I shouldn't unit-test? Grateful for any suggestions.
ended up just patching/mocking the return values of whatever I didn't write and wrote an assertEquals
Would you folks have any suggestions for what IDE to use if I'll be doing QA with Python? I've been using vscode for a few years now, but I've seen some QA developers using PyCharm. I'm wondering if there is any reason to use one over the other?
This question is tied to the fact that I am learning version control, and will be tasked with choosing what editor I'll be using.
Thanks in advance. 😄
Anyone have a good recommendation for a 'why use Pytest' article? Trying to push my team to cutover to using it but a lot of folks are still using Unittest for everything
Yeah, just trying to see if anyone has a good source I can throw at them; why make my own arguments when someone else already wrote a better one 😄
IMO fixtures/etc are a powerful enough reason to do it
Less code with pytest, not to be underestimated.
FWIW on this one people like both but I don't think either is a killer improvement over the other; I would generally recommend to use the same IDE as the rest of your team as a starting point so that you 're all using the same toolset, but if that's not applicable or doesn't matter then I'd say it's a coin flip.
Hello all, fairly new to working with pytest. Running into an issue where all tests report passing but the pytest process is hanging and not letting the test run complete. running with --setup-show it reports that the session scoped fixture is calling the teardown. This fixture is launching a mock api server that the projecct I am testing is calling endpoint from. Any thoughts on how to troubleshoot the hanging / orphaned pytest.exe process I am seeing?
It's probably a non daemonic thread
PyCharm pro has a unit test coverage tool which I needed, I think VSCode can also? but not sure..
It's just coverage.py, a pure python module
Hmm, you might be right. I haven't tried any coverage tool outside pycharm though
I have. And PyCharm will literally ask you before if you want to install coverage.py into the python environment if you try to run coverage the first time on a project.
If I want to do test of functions that do api calls should I create variables of different responses and use Mock to make the call return per Test. Or is there a better way to test around api, I do not want to spend more on the api calls than I already am.
idk if this is related to unit testing
however is python a good language to run physics experiments
ping me if you can help me plsssss
I usually prefer writing functions that wraps the http calls. Those functions are easier to monkey patch than mocking responses from the requests or httpx libraries.
You might like vcr
hey, quick question, let's say I have functions foo and bar and foo calls bar.
If I write a test that only calls foo, and calls bar implicitly, coverage will still show bar as covered. correct?
Is there a tool that can tell me which functions have tests just for them?
Yes, coverage will show all executed lines.
Afaik there is such tool. https://kodare.net/2019/10/18/which_unit.html is my little rant on this subject with a link to a crappy hack I made for it
This entire thing is a problem for mutation testing...
The term mutation testing was new to me, but in general I don’t think it is a problem when a unit test will indirectly “test” underlying functions. Otherwise you would need to write a corresponding test for each function, and that sounds a bit strange to me since the implementation behind the code shouldn’t be that much relevant (except for monkey patching I/O).
In short: it’s a good thing aiming for as few unit tests as possible.
But mutation testing is probably a different use case 😀
well... I have a few thousand lines of code for procedural generation, which at the end just feed into one main function. Even if there is "output" and even if it's "technically well formed" the output can still look wrong.
And the mistakes are cumulative. If I can see that the outcome is wrong, it's not obvious which step introduced the "technically correct" calculation.
So the problem that the main functions works and technically "things are covered" isn't all that helpful. I can think of some specific cases where I want functions to do very specific transformations. But I have to cross my t's that I'm actually doing that.
Also, the most recent thing I did with that particular code was rewriting parts to make it compatible with multiprocessing and at that point I only have "???", "timeout" and "something that the code doesn't fail over, but it doesn't look right either".
That sounds more like an integration test?
While refactoring, adding unit tests to the extracted code would sound reasonable to me and using TDD would be even better!
What I meant with as few unit tests as possible, is to find a balance between testing one thing, but not necessarily test every single part of a feature.
Yep, and I agree, I just know I have too few 🙂
There's some problems with mutation testing that is coverage guided where it will run too many tests, slowing everything down. Think of it like this: if you have a strip_prefix function in your code base, you don't want to rerun tests for everything that uses that function if you are working on it. You want to make sure you have 100% mutation coverage for that function itself and only run the tests specifically for that function when working on it. Otherwise the complexity grows exponentially.
I'm the author of mutmut btw, so I care a bit about this subject :P
Surely there has to be a better way to vary over n parameters than an nx nested for loop?
Hi, what is the best way to debug a unit test?
All my test fail on one branch fail but when I change to the dev branch for example they all pass for some weird reason
Fixed my issue
I would suggest to give map with defined functions a try, extracting the parts into smaller steps (functions).
Have u tried reading the errors
Vscode has nice visual debug to go though tests
what was it?
I have
Yeah I used pycharm as IDE but will keep that in mind.
I am writing documentation for a package that I am creating and I need to put code examples within the SDK in many places, what is the best way of doing this so it is DRY, automated, and tested easily?
To write code documentation I am basically grabbing code examples from the tests directory and putting them in the docstrings. However, this is a problem because every time the tests update then the documentation would also need to be updated as well, which could create a lot of work. Is there a better way of doing this?
feel free to @ me
what do you use for documentation compiling from docstrings
material mkdocs
anyway => sphinx has features to embed file contents into docstrings
possible at least with Google style docstrings or some default sphinx syntax
mkdocs plugins may be having something similar
the only thing that I found for mkdocs was code include plugin, but it seems like it is unpopular because it only has 11 stars, and makes me a bit anxious about using it
.. include:: inclusion.txt
:literal:
https://docutils.sourceforge.io/docs/ref/rst/directives.html#including-an-external-document-fragment
https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html
Ensuring you will use it together with Sphinx autodoc
you will receive file embeddement in docstrings for documentation generation from docstrings
I think this is for restructured text, but I am using markdown
is there any way to do it with markdown because the whole project is already written in markdown?
sphinx supports markdown too https://www.sphinx-doc.org/en/master/usage/markdown.html
hmm maybe I'll have to move over to sphinx
https://myst-parser.readthedocs.io/en/latest/syntax/optional.html it will involve using MyST language though
that has entirely different compatibility
https://myst-parser.readthedocs.io/en/latest/syntax/code_and_apis.html#including-code-from-files
including code from files is still available though ^_^, there is some need for adjustments to use autodoc2 instead of autodoc potentially
hmmm, it seems like there is no easy way maybe
should I just use the mkdocs code include plugin?
I wrote my own tooling for that when we build the docs for iommi. I just wasn't close to satisfied with what I could find.
is it open source package by any chance?
Those aren't screenshots, they're iframes of the actual html that the view with produce too. WAY better than screenshots for so many reasons.
weeell.. it's open source in that it's in the iommi code base. I haven't broken it out to a separate package though as I still want the flexibility of changing it all without having to make a new release of some other package.
is it normal you need to change the tests and more over, the examples? does that mean you cannot afford backward compatibility? does that mean client code will break often?
well every I have a test for creating an object and then changing all of its getters and setters. I could include creating the object in the documentation straight from the test instead of writing it again in the docstrings
yeah but aside from the technical difficulty: if that happens often, does that mean your library upgrade will break all client code because it's too often breaking backward compatibility?
imo, even if your problem of auto-generating things is legit, you also might have an issue that you seem to struggle with a highly frequently changing specification. and for a client that reads your doc, if every interface changes from one release to another, it can become extremely frustrating
(pandas for example, rarely breaks its example set: previous examples are likely to still be good examples from one release to another; you might have new examples, but "breaking" examples seem to be more rare). if you make that kind of doc, I assume you target some customers. so maybe it's interesting to think about what kind of robustness you can guarantee for them
hi is there a good reference to learn pytest ?
Google: pytest official documentation
Hello! Is there a methodogy to test a function with all possible outcomes other than simply writing a test for each possible case?
lets say I have the following example and someone uses a string and a dictionary as arguments.
def test(num1,num2):
return num1+num2
I am trying to avoid try except solutions because in most cases it's simply sweeping the problem under the rug
should I write each specific such case on hand? Is there a "simple" way to make unit testing for all possible arguments?
this is a very good question
the short answer => it is best solved by static typing, that can be provided by Mypy (or Pyright)
def test(num1: int,num2: int) -> int:
return num1+num2
you type acceptable type values of an object
and Mypy enforces that no code parts invoke this function with incorrect value types
the hard trick is... you need all your code mypyed preferably in all covering fashion
https://careers.wolt.com/en/blog/tech/professional-grade-mypy-configuration
otherwise some code can propagate Any types and screwing typing system at least in some places
as helpful friend, good to use pydantic base models when you can (for data transfers)
anything that gets into them, has automated ensurance that on output they will have correct type
but as some point typing in python has its limits
and it is easier will be... just switching to another language at some point
I learned golang and learning java for those purposes.
there is python substition btw for those purposes. using libraries with fakery data generation, using libraries like schemathesis that will check your OpenAPI typing declaration of web endpoints and will try all possible data generated and inputed into them
but those are all half measures again, making many extra moves for one simple idea => easier to have static typed language than language with many many crutches to substitute it
that is VERY interesting. I considered reading golang even though the hard start I will face
start from this one, it is quite easy
also.. learning golang and its typing system will give you understanding how to use python typing and mypy.
i think without experience of static typed language, it is hard to get python substitutions for this, at least i was not able until learned golang
transferable experience between languages
Every single thing you wrote gave me great insight. I will read through all of the modules. I learned about pydantic through fastAPI but I didn't make use out of it outside of fastAPI. I am working with people that care little on testing. some example is crawling information and their code is full of try excepts with no logging. Yes the problem I am facing is steps before unit testing but will help me put some things in order
pydantic base models are perfect to be used... as data transfer objects across code.
You know.. it is better at some point using class of data instead of dictionaries?
but classes are sometimes needed quite simple, just for data, that is where python dataclasses came in https://docs.python.org/3/library/dataclasses.html, as they boilerplate constructor of class, hashing and etc
pydantic base models are even cooler, since they ensure correct type of values on output.
Quite safe and good data transfers of data objects across your python code. At least some typing safe place in a quite important place.
with having good self documentation to all possible present data (obviously way better than just using dictionaries that could be having anything inside entered at any place and deleted at any place)
plus they give you for free boilerplated serializers and deserializers into dict and json! (and even openapi schema)
class Point(BaseModel):
x: int
y: int
and that's it. you don't need to test if they will have correct types any longer. this is ensured at runtime automatically
runtime type validation
for something that simple, wouldn't it be same as you wrote above?
def test(num1: int,num2: int) -> any:
def test(num1: int,num2: int) -> int:
return num1+num2
already wrote example
you can rewrite it in a better way... with reusability through using generics
once inserted type will propagate to others like automatically switching that all expected types are int or double and etc
yes you did. I am asking if the outcome/response of someone calling this function with wrong types would be the same
but it's my bad to ask that as I should just.... test it 😄 which I plan to
if u insert ints, and u have known that + operator yields same type value (your language ensures that), then it will yield int too
using Any is bad thing that preferably should be never ever used
because it is kind of synonym for untyped anything
used only as crutch in the most difficult spots
using Any you forfeit static typing by Mypy in this place (and it propagates (very quickly) as untyped in other code places)
fair. of course. my mistake to even give it as an example. I know about pydantic's Union for one type or the other, I believe there is a built-in similar way? At this point I am wasting your time with very simple things I can just google. I will look over all our messages again. thank you VERY much
#type-hinting we have this place to ask typing questions
plus you can give a full reading to python typing documentation https://docs.python.org/3/library/typing.html
Union[int, double] is a valid inbuilt typing
since 3.10 version it is simplified to int | double
but for test function above, better using generics because...
def test(num1: int | float,num2: int | float) -> int | float:
return num1+num2
check this code for example
if num1 is int
you can still insert num2 as float
and return can be int | float or even error if conversion failed for some reason
in next code places this function will give you undecided int OR float
while you wish it being explicitely int for example if you submitted all ints into this function
here where Generics come in (concept you will learn how to use in Golang)
T = TypeVar('T', int, float)
class Summator(Generic[T]):
def sum(self, a: T, b: T) -> T:
return a+b
this code once used will propagate correct types
if u will submit into a int, you will have static typing error by mypy, if you will try not int into b
and it will correctly show static typed yield result as int if u submitted int, for other code places
Generic fixes type for multiple objects into same one basically.
making reusable function for multiple types used
this is concept of static typing... all types are known at compile time (before code is run) ^_^
this Generic stuff allows you to define them being known before code is run.
Since it can get known type of what you are going to submit, and thus calculating what will be type result before code is run
Btw, in case of tests, there is option to use pytest parametrized tests for easy fast testing all different inputs and outcomes
It is again substitution though. In typed language it would not have been necessary to test
Good evening people. I have a question, but I am quite new. Please feel free to delete my comment if it doesn't belong here. Does anyone use Kiwi TCMS?
has anyone worked with adb or uiautomator?
Hi is It safe to have asyncio_mode = true configuration and doesn't use decarator @pytest.mark.asyncio?
You mean asyncio_mode=auto
I personally prefer strict but if you don't plan to add anyio or trio tests it's totally safe
Super! Thank you
Have you tried using it? I'm using it as mentioned here https://docs.pytest.org/en/7.1.x/how-to/parametrize.html but it's giving me an error saying that my function requires positional arguments
sure. sorry can't help you because you aren't showing your code
import pytest
from django.test import TestCase
class TestP(TestCase):
@pytest.mark.parametrize("arg1, arg2", [(1, 2), (1, 3)])
def test_p(self, arg1, arg2):
#something
pass
Running this through the debug option in pycharm
wtf is this 
use this or this.
import pytest
@pytest.mock.parametrize("arg1, arg2", [(1, 2), (1, 3)])
def test_p1(arg1, arg2):
#something
pass
@pytest.mark.parametrize("arg1, arg2", [(1, 2), (1, 3)])
class TestGrouped:
def test_p2(self, arg1, arg2):
#something
pass
launching with pytest -k test_p
ensure to have pytest.ini and installed pytest-django
[pytest]
DJANGO_SETTINGS_MODULE = core.settings
python_files = tests.py test_*.py *_tests.py
pytest parametrize for pytest tests, not for unittest
oh
P.S. unittest tests are backward compatible with pytest. no need to refactor them all right away to migrate to pytest
Thanks
how to use airesponses if I built a custom class that uses ClientSession? I mock full URL and then receive ClientConnectionError? So my methods GET/PUT/DELETE just use self._session.get/put/delete inside them. Not even an overloading
Hello everyone, I'm new here and I wanted to ask a question about mutants that I'm having trouble with in an exercise, and I wanted to know where I can send this question within this Discord.
You can send your question here if you're still having difficulty.
Mutants? are you using mutmut?
You also use mutmut?
Hello there
any idea why my unit test doesn't get the environment variables but my actual program does ? especially when I write them in the docker-compose or dockerfile, they work for my program but now I declare them in the pycharm unittest configuration and it doesn't detect them
What variables does it see?
only the ones I write in a config.ini file
but it ignores the ones I send through pycharm
imma try the actual project one sec
I'm going to try something
yeah so my actual django project doesn't ignore the environment variables when I execute the dockerfile through pycharm
but my unittest ignores the variables for some reason 😦
and it doesn't even find the config file in the variables I pass through pycharm, it finds it because I write the path in the code in case it doesn't find it, like a default option
so yeah
Imma investigate a bit more
How does the test use the environment variables?
so weird
it calls them and assigns them to variables and then throws an exception
if the variable doesn't exist
or it's empty after having assigned the value
that's why the test fails even tho it works on the actual program
Is the test for function behaviour based on existence of the environment variables?
I want to send the environment variables through pycharm for the test so I don't have to write them hardcoded on a config file
kind of
the test calls a program function that actually verifies the variables exist, the function throws an exception if something doesn't exist and the test fails if the exception in that function is thrown
and passes if nothing in that function is thrown (everything exists)
so it is really weird
I have already informed the senior so I'm chilling now looking at something else but it's really weirddddddddddd
Hi, I want to create class and package diagram of my project with pyreverse. It fails continuously. Is there anyone could help ?
Hello ! Any one here available to give me a little help on this ? :3
https://discordapp.com/channels/267624335836053506/1117216278298501150
im new to unit testing can anyone help me with some lines of code quick
im trying to find every comment from https://www.klix.ba/sport/tenis/djokovic-je-apsolutni-rekorder-po-zaradi-ima-cak-32-miliona-eura-vise-od-prvog-pratitelja/230612118/komentari containing the word "cestitam" but it just closes out
import time
from selenium.webdriver.common.by import By
from credentials import mojUsername
from credentials import mojPassword
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("disable-notifications")
chrome_options.add_argument("disable-popup-blocking")
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://www.klix.ba')
driver.maximize_window()
time.sleep(4)
header = driver.find_element(By.TAG_NAME, "header")
loginButton = header.find_element(By.ID, "user")
loginButton.click()
time.sleep(2)
authenticationModal = driver.find_element(By.ID, "authentication-modal")
username = authenticationModal.find_element(By.NAME, "username")
password = authenticationModal.find_element(By.ID, "lpassword")
submit_button = authenticationModal.find_element(By.CSS_SELECTOR, 'button[type="submit"]')
username.send_keys(mojUsername())
password.send_keys(mojPassword())
submit_button.click()
time.sleep(3)
sportBtn = driver.find_element(By.LINK_TEXT, "Sport")
sportBtn.click()
time.sleep(3)
vijest = driver.find_element(By.LINK_TEXT, "Đoković je apsolutni rekorder po zaradi, ima čak 32 miliona eura više od prvog pratitelja")
vijest.click()
time.sleep(3)
sviAElementi = driver.find_elements(By.TAG_NAME, "a")
for aElement in sviAElementi:
if "prikaži sve komentare" in aElement.text.lower():
aElement.click()
break
commentWall = driver.find_element(By.ID, 'comments_display')
for wall in commentWall:
comments = wall.find_elements(By.CLASS_NAME, 'komentar')
likeButtons = wall.find_elements(By.CLASS_NAME, 'voteUp')
for comment, likeButton in zip(comments, likeButtons):
if "Cestitam" in comment.text.lower():
likeButton.click()
pass
time.sleep(5)```
it just closes out and doesnt click the like button
hi, feeling difficult in understanding the below code.
from unittest.mock import patch
from fetch_data_from_db import *
from unittest.mock import MagicMock
def configure_connection(mock_conections: MagicMock, mock_cursor_context_manager: MagicMock):
mock_cursor = MagicMock()
mock_cursor.__enter__.return_value = mock_cursor_context_manager
mock_conn = MagicMock()
mock_conn.cursor.return_value = mock_cursor
mock_conections.__getitem__.side_effect = {"default":mock_conn}.__getitem__
@patch("common.db.connections")
def test_manager(self, mock_connections):
mock_cursor_context_manager = MagicMock()
def execute_side_effect(query):
expected_query = """
stub_for_expected_query
"""
if query == expected_query:
mock_cursor_context_manager.description = ["column_names"]
mock_cursor_context_manager.description = ["values"]
else:
mock_cursor_context_manager.description = []
mock_cursor_context_manager.description = []
mock_cursor_context_manager.execute.side_effect = execute_side_effect
configure_connection(mock_connections, mock_cursor_context_manager)
can anyone please explain..
Hello folks! I have some old Selenium tests at my job that we’re looking to start running again. I understand that Selenium IDE is deprecated, but I was able to run the tests on the Chrome extension.
Would it be alright to look into using WebDriver or are there any other alternatives?
I’m thinking we will have to toss the tests, but if it’s possible to use them still then that would be great.
Thank you in advance.
How do I deal with functions that use floating point numbers and hence may lose precision when doing unit tests? Do I simply give the result a margin of error?
math.is_close()
Yes.
Update: Ned's answer is better ;)
I know this one is about unit testing but we were playing around with the idea of somehow gathering coverage on e2e tests for web services.
@river pilot have you ever seen anyone experimenting with such crazy ideas?
Thanks!
i think people do that for sure.
you'd have to start each service with coverage, and shut it down cleanly to write the data.
The multi process mode of coverage and then the merge command does this very easily. I've done that. Never had problems.
guys, do you have any ideas of using AI or ML in API testing?
Testing should be precise. ML is not exactly precise
Yeah. Best way: not using it.
Because it will be to meaningless, noisy and super highly implementation details attached anyway even if it did smth.
you will get a lot of fragile test tech debt, that will be all the time breaking and making you dissapointed in testing and preventing any refactoring (moving you to direction opposite from the why tests were needed in the first place)
I mean, if you don't know how to write python syntax I think it can help a lot. But otherwise it seems bad to me....
I think I'd consider ChatGPT if I wanted to write code in a language that was new to me but the language was well represented in the training set of ChatGPT.
I agree with @maiden pawn and @lament heath , thanks for ur words
I tried explaining this to my higher ups much before, but he is not understanding
Seeing chatGPT he wants some product for API testing with Ai
Btw, this a place where i intern, i wanna quit cuz of this, what do i even do

There's a lot of people getting AI psychosis nowadays yea
Yes, i agree Ai is great, i dont deny it or i dont hate it
But testing is not a place to use it, testing APIs is very sepcific, like it depends a lot on ur application, how can using AI help here
I don't think that's the problem. The problem with using AI to write tests is that tests are the parts the humans should be writing the most!
That's the part that verifies that the code does what you want. You can then use AI tools to generate the code to test maybe (although I'm skeptical about that)
I think AI can generate test cases, but very general not specific
AI can do anything where it has already seen the correct answer :P
(plus some hallucination noise of course)
Like say my application has id, of the form UHJXXXX where X denote some integer,
But an AI model would generate inteegers for id as test cases, like id=2 id=35
But still @maiden pawn, what part of api testing do u think can be done by AI ML, like testcase generation or... ?
(It might be not tooo proper, i just want to do it and show it failing to my manager)
He will prolly tell i did it wrong but whatever
I mean, just try it yea. Maybe you can use it to generate a bunch of the code then fix it.
Try it for an hour, then you can be specific in your push back.
Can we stop calling super size Ego t9 ai, those models are text predictors that are simply so huge and powerful that the output may seem reasonable, and their output is Sometimes immensely helpful, but the errors are painfully cringe as well
I think we lost that battle. I like how lisp systems from the 70s are also called "AI" though. It sets expectations better :P
regular user is dumb enough to be not recognizing those limitations already. ¯_(ツ)_/¯
https://www.bbc.com/news/world-us-canada-65735769 absolutely dumb.
The lawyer told the judge he did not know content from the artificial intelligence could be false.
@old venture a bit of jokes on topic
It's showing the html yea. What did you expect it to show?
That's kinda lawyer seems like first in line to get replaced by llama with a verify feedback loop to begin with
It does show where the error is. And it helpfully shows the string that string isn't found in.
I mean.. unit testing is just python code, it's not magic.
I am getting a weird error in pytest and flask with ckeditor . Here is the post I made on stackoverflow with more detail. https://stackoverflow.com/questions/76486946/i-am-getting-an-error-when-running-pytest-but-the-code-is-working-when-i-use-fla . If anyone knows the answer ping me please and thank you.
The code was working before I added ckeditor but when I run pytest -q --capture=no I get an error.
Here is the documentation for ckeditor https://flask-ckeditor.readthedocs.io/en/latest/basic.html#
Why not try what the error message tells you to try?
In the register call, pass the name.
But in the register call I don't use it. At least I don't think I do.
@proud nebula I assume @auth.route("/register", methods = ['POST', 'GET']) def register() is not the call of the register function?
Is return render_template(register.html) the call of the register function. Because I don't need to pass anything ckeditor because that makes no sense.
no, the registration of ckeditor blueprint is the problem. Which seems weird. I'd guess it's double initialized somehow? Maybe you're double initializing your entire app?
I'd probably put a breakpoint and check the first time it gets there and how it's different from the second
I think I know what the problem is now.
app = create_app(PytestConfig), is located at 2 locations in pytest.
PytestConfig is in config.py and I have multiple config like the example below. If I turn app = create_app(PytestConfig) into a fixture do you think that would work even though it is located at 2 examples?
https://flask.palletsprojects.com/en/2.3.x/config/
class Config(object):
TESTING = False
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DATABASE_URI = "sqlite:////tmp/foo.db"
class TestingConfig(Config):
DATABASE_URI = 'sqlite:///:memory:'
TESTING = True
ah, that sounds reasonable
Thank you and hopefully that fixes it.
can a flask app be destroyed when you're done with it or something?
Maybe that could also be a solution...
I don't know . I never heard of anything like that, so I would have to google. I was just thinking of putting the fixture in app =.....
You can delete the db and I do that in a fixture. I am going to test the fixture now.
Maybe there's some pytest-flask package you should be using to get the app?
Sorry just moving some code around still testing thanks for the suggestions
I am trying something but parts are still not working.
tests/conftest.py
Here the code is working.
@pytest.fixture()
def create_app():
app = create_app(PytestConfig)
return app
@pytest.fixture()
def create_db(create_app):
db = SQLAlchemy(create_app)
return db
app = create_app
db = create_db(app)
# app and db are used in the below in the code.
...
The problem is I need db for the class usertest. But I am getting an error. I tried a few combos of importing the fixtures to function but I assume I am screwing up.
test/models.py
def create_db_again(create_db):
return create_db
db = create_db_again
db = create_db_again
class UserTest(UserMixin, db.Model):
...
I will update the error if the below doesn't work
How do I pass on the fixture to the functions. Unless someone thinks I should try something else. I am currently trying creating and teardown/destroy the app.
I think I got it working I got rid of the fixture forcreate_db and just imported from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
Please, read pytest's docs about fixtures. You are using fixtures incorrectly.
You can't call them directly. You must include them as arguments to tests/other fixtures
Okay I will thanks my example is above is a mess because I thought it was like db = sqlalchemy(app) but is like db = sqlalchemy() Hopefully this fixes the original error with ckeditor
I got ckeditor error working I can share how if anyone is curious
Can I parametrize and pass it on to fixture? Then how would I pass on the fixture with the param to a another fixture? Assuming this is possible
Be more specific. Show us what you want to do.
pytest-fixture-classes allows you to do factory fixtures rather easily.
When you say "pytest-fixture-classes" , do you mean classes or fixtures? sorry for the dumb question
Fixture classes. It's both fixtures and classes.
But I can't be sure if it solves your problem until you describe what you want.
https://github.com/demberto/hashids-python
How can I use pipx installed pytest for this layout?
It errors with ModuleNotFoundError with the package name.
I also installed the package in editable mode in a venv
pipx installed pytest is installed in a fresh virtual environment so it won't see the editable installed package installed in a different environment
You probably don't want to use pytest via pipx
i think this should be reported as an issue. didn't pytest undergo a lot of work to be pipx compatible? or was it tox?
pytest trashes the venv with a ton of deps, i avoid installing anything in the venv generally.
It definitely wasn't pytest
tox 3 worked with pipx
the venv is where you should install your development tools like tox, no?
Hello
I have a function like this that inserts an award in a table
def insert_award(award):
with contextmanager(get_db)() as session:
obj_db = Award(**award)
obj_db.created_at = datetime.utcnow()
session.add(obj_db)
session.commit()
session.refresh(obj_db)
related functions to create the engine and link thee session with the db
SessionLocal = None
if app_settings.database_url:
engine = create_engine(app_settings.database_url)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def get_db() -> Generator:
try:
db = None
if SessionLocal:
db = SessionLocal()
yield db
finally:
if db:
db.close()
im trying to patch this get_db in ccontext manager (or the session, or whatever can be patched at this point) like this
@patch("app.db.session.get_db", new=mock_get_db)
def test_insert_award():
insert_award(award)
I have tried almost every variation I can think of this including using monkeypatch, patch.object creating a with block but no matter what it always uses the get_db instead of the mock_get_db function (which is the same function but has a different url)
Anyone has an idea what can I do here?
I'd prefer to have as many tools in a shared location as possible. The venv should only have package dependencies ideally. Infact I have been using coverage.py from pipx without any issues.
Keeping everything in the venv is a space waste for one, and you need to keep it updated for every venv
I pin all my package versions, including dev tools, to reduce version skew friction. So different projects will be using slightly different versions of tools.
Same here. It is quite nice to have the freedom of deleting the venv and rebuilding it with a simple makefile. Refreshing to reset the stage easily.
You are working against how the tools are made to be used. That's a bad idea.
Can anyone recommend me a GUI testing framework/tool for creating automated unit tests for pyQt GUIs? It doesn't have to be free but something like the official qt QA tool which costs several hundred dollars per month is out of my budget.
sessionmaker instances have configure method that you could use
You can specify different engine here, or a live connection
e.g.
async with engine.connect() as conn:
transaction = await conn.begin()
SessionLocal.configure(bind=conn)
Thank you for your answer, sadly Im not allow to modify insert_award code which is why Im having so much issues. If I could either pass a session or a config for the session it would be much easier
And you don't have to, you need to modify get_db
Same thing, I cannot modify anything in the original code
well, actually that was before, I had a talk with my tech leader and we decided another approach. I don't think it was possible to do it the way it was planned originally
Have you taken a look at Qt Test?
I would appreciate anyone taking this for a spin and letting me know how it went. This is a daemon that runs tests so you don't have to redo the initialization / import logic. Python 3.10+:
https://github.com/JamesHutchison/pytest-hot-reloading/
i like this, even tho it comes with a BFG 9000 style footgun - will try to make some time to try it this weekend
What's the footgun?
Python is a hot reload hostile language and it compound's with none of the pytest internals being reload aware, so there's quite some potential for mayhem on anything that's using import Time registration or metaprogramming and one has to play whack a mole
It should work ok if you're working with tests that can be parallelized or ran in any order. For libraries that may mutate things with each test suite run, there's an option to register a workaround function that can do whatever is necessary to fix things. pytest-django is an example where a workaround was created because it mutates the connection settings in the global connection pool
I made sure the library worked with MegaMock, which uses the varname library (which uses the AST)
Which is kinda my point, I'm aware of various library ecosystems that are extremely likely to blowing up due to import time registration problems
Feel free to create an issue on github if you find an incompatibility and we can create a workaround. Ultimately, the goal is to work with all major libraries where someone might benefit from hot reloading
I've tried to do stuff like this a few times with mutmut. Always looks great initially and then you find some details that don't work and after a long while the horror of it sets in :)
Maybe I’m misunderstanding the problem, but if there’s a footgun in there - wouldn’t writing unit tests with depending state be the actual one (and not hot reloading per se)?
there is numerous library systems that use runtime registration systems - instances of those objects would potentially degrade or orphan on certain types of hot reload
Wouldn’t these kind of library systems be the ones you’d typically mock in a unit test anyway?
well, if you use them for integration or system tests its ging to be a storm
Integration & system tests are a different kind of beast (speaking of foot-guns) 😄
Those aren’t probably the main targets for hot reloading.
They involuntary are, smaller unittests are so quick that hot reload has no.wins
Makes sense!
i am getting this while running unit test for fastapi app using pytest.
`E RuntimeError: Task <Task pending name='anyio.from_thread.BlockingPortal._call_func' coro=<BlockingPortal._call_func() running at /home/miicon/Documents/services/protocol_cs/venv/lib/python3.10/site-packages/anyio/from_thread.py:217> cb=[TaskGroup._spawn.<locals>.task_done() at /home/miicon/Documents/services/protocol_cs/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:661]> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop
asyncpg/protocol/protocol.pyx:338: RuntimeError
==================================================================== short test summary info ====================================================================
FAILED tests/test_routes.py::test_invalid_email_login - RuntimeError: Task <Task pending name='anyio.from_thread.BlockingPortal._call_func' coro=<BlockingPortal._call_func() running at /home/miicon/Documents/serv...`
the tests that i was running:
`def test_successful_login():
data = {'email': 'k@gmail.com', 'password': '123'}
response = client.post("/users/sign-in/", json=data)
assert response.status_code == 200
def test_invalid_email_login():
data = {'email': 'icuhroj@gmail.com', 'password': '123'}
response = client.post("/users/sign-in/", json=data)
assert response.status_code == 401`
pls help
my views are async and tests works if i run these two test separately. how can i solve this
maybe that's a bit of a strong statement. The wins are probably smaller, but if it's a huge set of tests that can still be a long time. But yea, most likely you want to just select relevant tests instead of hot reload, that's where the big gain is.
indeed, i may have overpainted it a bit, my impression is that the win of hot reload is basically with state one can hold onto and setup cost one can pre-pay/keep
I can imagine scenarios where this is very important. Like if you are loading a huge model into memory or something.
I'm fairly strict on considering tests that potentially need gigabyte's of prepared online data at least integration level,
🤷♂️ It'd be better if there was an authority that had literal trademark rights on words, or if there was a consensus system with strict rules like species names in science... but we have a de facto chaos system for names in programming so...
like how "REST" means "json over http" nowadays, even though that was not at all what the original inventor of the term meant
Sometimes it's useful to fight for the words, sometimes it's best to just accept the common usage even if it's a bit stupid :P
"Give me the wisdom to know which is which" :P
Well consistently letting Sales win the game on what words mean in Tech has a price
Just look what they did to agile
I guess.. depends on how wide you define "sales". If you include bloggers and "thoughtleaders" then yea 100%. But I think it's a bit more than that. At least with REST it was basically a marginally useful idea from the get go :P
rest as it was originally extrapolated from observation and formalized is quite awesome, its quite tragic how the word is used these days
Looks like you're constructing your database connection as an import side effect, you should use a lifespan context manager instead
hello guys,
any suggestion about regression test, when the services use redis ?
the communication between service is rpush / blpop
the main problem is, the function in python script just return void (but in flow function is use rpush/blpop)
how i assume the past is correct (talk about data) if function just return void / None
Not exactly, a small unit test SHOULD be quick, however, with a django monlith, this happens:
- Tests are discovered by loading all 10,000+ of your ball-of-mud monolith's files
- Your 2,000+ migrations are imported so that the final state can be computed, even though you've disabled migrations already
- The test database is built, if needed.
So then your simple test with one model ends up taking 45 seconds to run (0.05 seconds actual test time)
To make things worse, many developers have run tests out of a bind mounted docker container unaware of how slow it makes it, so the I/O is horrendous. That 45 seconds turns into something much worse, and I haven't even mentioned running with the debugger on.
Can we coin this scenario a unittest that has gone to the systems Test hill to die
Hey if you got a silver bullet I'm sure its worth a lot of money
Actually, hot reloading is probably the closest thing and I'm not getting paid squat.
indeed, its awesome , i absolute love the idea, but its important to keep in mind that python itself is hostile to hot reloading due to its nature
The key to reasonably approachable hot code reloading is enablement of safe registration/replacement/removal
eh, ok, I don't know why you thought it was a good idea to claim django is broken with migrations. It's not.
Nobody claimed it's broke?
You can and should squash old migrations but it's not perfect and will still eat up time
I was stating the migrations are still imported and they absolutely are. They usually are not ran but some devs stuff "static" data into a migration and build tests against it and then you gotta run them until someone gets around to fixing that.
There's also migrations that enable database features, etc
you said the feature to ignore migrations during tests doesn't work?
I use it, and it's great
I think the squash migrations usecase is overstated. A lot.
Just don't look in the migrations folder and you'll be happier :P
ew, that's evil
I'm going to hold off on doubling down until I get a chance to recheck that things behave the same as they did a year ago when I originally investigated the issue. Back then, if you set it to SkipMigrations there was still a long delay as it went through the migration step even though it wasn't running migrations.
I have an issue to verify the hot reloading helps with that and I just haven't gotten to it yet
hmm, that's disturbing
ran one fast test now and it took ~1.1s total for pytest.
I put a hard crash in a migration for that app and it was never triggered though, so I don't think that's why pytest was that slow
meh, and hammett doesn't work on this project. Will have to look at that later.
Oh neat, I wasn't aware of hammett
I have a to do item to create a nose style test discovery plugin but maybe hammett obsoletes that?
some fiddling later... got one test to run in 913ms in hammett. Better than pytest 1.3s but still surprisingly slow.
hammett is like a super alpha quality pytest rewrite... it does nose/pytest style test discovery ok I think. Plus it has basic support for pytest fixtures and some plugins work.
it does some evil stuff to get that compatibility to work heh. sys.modules['pytest'] = hammett for example
The primary use case for the nose test discovery is VS code's auto test discover on save
It's a bit obnoxious when test discovery takes over a minute
How is that different from pytest? Afaik nose is just super old and abandoned pytest
Nose tests traverses the file system to look for tests based on filename convention and then class / function name convention
I'm contrast, pytest actually executes the test code. In many cases the results are often identical except that nose can't easily support extracting parametrized tests
Since parametrized tests could come from a run time variable
PyCharm runs its own logic which is basically nose test discovery on the file you're looking at. I don't think it supports parametrized tests either (you run all subtests rather than being able to target just one)
I don't think that's right. I wrote Hammett so I think I have some insight here. Maybe you're not using pytest test selection properly. If you specify filename it won't import everything.
I'm pretty sure pytest --collect-only will import the test code
Oh. Yea it will. Hammett too.
I'm not sure about individual file name behavior. VS code isn't that smart
Hanmett caches it though?
Pycharm does foo/bar.py::test_baz which will avoid extra imports. Nose can't do better than that.
Right but PyCharm is using custom logic to know that's a test in the first place.
Hmm. Don't think so. But I remember experimenting with caching. 🤷♂️
Sure. To get the little icon in the IDE. That's probably some very naive code.
What's the point of listing the tests fast?
Because in VS Code it doesn't have any logic. It calls pytest --collect-only at the root level and then parses the output. If you write a test and then want to run it, you have to wait for that to finish if you want to use the UI
Lol. That's enormously stupid. A regex of \w+test_ is better than that.
The few false positives will be worth it a thousand times over.
Well the regex is basically the nose plugin I would write
There's also tests that inherit from a class with TestCase in the name
That covers most of them
The last part is converting the pytest output so that the subtests are used to create a pass / fail result for the parametrized test
You don't need that check. It'll remove false positives but not enough to make a big difference imo.
I think you mean false negatives? It would be to detect tests that don't have "Test" in the name but inherit from TestCase
Ah. I was unclear. My regex will just catch all methods and functions starting with test_. No matter where they are.
That has false positives if people name functions test_ that aren't tests.
Ah yeah, that makes sense
Yeah that might be better. The containing class still needs to be captured but one can skip looking at the parent class
Or maybe another really stupid regex :)
You can be fancy and use the ast module too. It's quite fast.
ast requires importing the code though?
nope
I suspect parsing text is faster
yea a regex is faster, but you'd be surprised how fast ast parsing is
thanks but . can you please explain or give me an example ? sorry i didnt understand it proprtly cause i am new to this
In python, import will execute the module ("file"). A def line will create a function. A class line will create a class. All the code inside the class will be executed to create the class. This means you must be very careful of code written on this level. Example:
this_is_executed_on_import()
class Foo:
this_is_executed_on_import()
def foo(self):
not_this()
def foo():
not_this()
oh i see, thank you ! i will look into it
So for work we use pytest, and I'm coming across some extremely weird behavior
I have a main function defined in the file named handler.py like so:
from package.collector import Collector
def main(event, context):
my_collector = Collector()
registered, unregistered = my_collector.get_registrations()
and this is the test file for it:
from package.handler import main
import pytest
@pytest.fixture
def client_response():
return {
"item1": 1,
"item2": 2,
}
def test_collector(mocker, client_response):
collector = mocker.patch("package.handler.Collector")
collector.get_registrations.return_value = client_response
main()
But the error I get is that the return value for get_registrations expected 2 outputs but got 0 - how is this possible if I'm forcing the return value to be something in the test?
registered, unregistered = my_collector.get_registrations() <- here it's a 2-tuple
collector.get_registrations.return_value = client_response <- here it's a dict
WHOOPS that's on me for messing up rewriting the code from the top of my head, this is what it should actually look like
from package.handler import main
import pytest
@pytest.fixture
def client_response():
return (
{"item1": 1,}.
{"item2": 2,}
(
def test_collector(mocker, client_response):
collector = mocker.patch("package.handler.Collector")
collector.get_registrations.return_value = client_response
main()
But the issue is still that despite me mocking the return value, I'm told that it returns nothing - not one or two variable,s it returns 0 variables
(expected 2, got 0)
copy paste the exact error and the exact code
It's on my work machine that I can't copy code from, and I'm not about to rewrite it all
But that sampel is the main stuff - I am literally setting the return value and it's not actually returning anything
You should discuss with your work why you are not allowed to work 🤣
that code has TWO syntax errors btw
We can't possibly guess the problem when you can't produce the code or the error message
ValueError: not enough values to unpack (expected 2, got 0)
have you used a debugger to step through and look at what happens?
another recommendation is to not use mocking and instead use dependency injection
Gimme one second to boot up my work laptop and retype the relevant code
You've already failed at retyping the code twice. This could be a problem with a stray comma or something, and then you retyping it incorrectly will not help.
Again: debugger, don't mock.
That's just on my retyping in a hurry and from memory, I've already quadruple checked for syntax or other errors
and babysitting a needy dog rn lol
main program (handler.py)
import logging
from package import Collector
from .constants import ACCOUNT_INFO
def main(event, context):
... # bunch of irrelevant code
logger = logging.getLogger()
logger.setLevel("DEBUG")
# example owner object is written out in the test file
owner = event["detail"]
host_collector = Collector(logger, ACCOUNT_INFO, owner)
# Collector initializes a varibale "self.owner_object" from the given "owner" object above
... # more unrelated code
registered_hosts, unregistered_hosts = host_collector.get_registrations() # error happens here
test file
import logging
import pytest
from package import Collector
from package.handler import main
@pytest.fixture
def logger():
return logging.getLogger()
@pytest.fixture
def example_owner_object():
return {
"HOST GORUP": [
{
"class": "some class",
"hostname": "host.domain.com"
"found": "2022-08-16T13:48:01.440623",
},
... # another item like the one above
]
}
@pytest.fixture
def colector_operations(logger, mocker, example_owner_object):
mock_collector = mocker.path("package.handler.Collector")
mock_collector.owner_object = example_owner_object
mock_collector.get_registrations.return_value = (
[{"host1": "1234"}, {"host2": "5678"},],
[{"host3": "1738"},],
)
# also tried setting it with a fixture
return mock_collector
# also tried the following
# collector_instance = Collector(logger, "1234", example_owner_object)
# return collector_instance
Can you make a runnable example GitHub repo?
I mean it's internal AWS code so no
I realize I can't step through and debug the pytest process because it's run through another internal AWS tool that does a lot of wrapping and such around the environment
I did do a silly debug step and used inspect.getsource for the function that's failing and it does come back fine in the test run
Something seems very wrong with your job heh. You don't seem to be able to actually get work done. I would focus on fixing that first.
I mean it's AWS, everything is internal lol
I'd normally go to my coworkers for help but the ones who worked on this project / related stuff are all away until wednesday
Not sure what jobs let you guys just copy paste internal code to the public
Well I ended up solving the issue
I had one variable in the Collector class that I was mocking elsewhere. That variable being mocked was being used in my functions, but also in other ones within the class. Long story short, the Collector class had method A which called method B which used that mocked variable, which would cause B to fail and thus A to fail
I strongly suggest people get their working environment set up. Amazing number of engineers will try to build stuff without being able to use the debugger, or other core components of what they are building, relying on print statements or deployments to a dev environment for everything...
This is why I will advocate:
- go make a dev container
- make your dev container support everything a dev would need to do for the project
- yes it takes time. Better to do it once than for every engineer
I mean do you want the run down of how we do things in AWS
- Every dev has a dedicated dev machine we remote into through our IDE / code editors
- We set it up to use the proprietary internal AWS dev tools (look up an app called
brazil, there's a few writeups online about it) - each package has what's called a "version set" which lists out any dependencies you have in terms of other AWS packages (not regular dependencies like a 3rd party python library, this specifically is for listing out AWS packages you need)
brazil acts kind of like venv or poetry but works on multiple different languages, and you don't enter into a shell environment like you would with venv's activate or poetry's shell commands. Instead you define a psuedo makefile to describe actions you want to take (IE format would run black, isort, flake8, etc. and another command test would run your unit tests).
When you run those commands, it runs them in a contained instance that you can't enter - so running format would do the specified actions and exit that environment immediately.
So there is no stepping into the code like you normally would with a program, at least that I've seen, but I've also only been here for 6 months and there are infinitely many things to learn here
It would be better to just run the python code directly, but you can use remote debugging in VS Code using the debugpy library
There's an option to wait for the debugger to attach prior to actually running
Every dev has a dedicated dev machine we remote into through our IDE / code editors
This is a good opportunity to use dev containers. You can install python on the dev container and have the python code run out of that. The dev container can also install other languages, and tools. Its a bit more standard to the direction to what the software industry is moving in. This frees you from running commands through another command, which creates incompatibilities.
Eh. One that isn't run by a paranoid idiot?
This is all very bad.
Honestly if you need a dev container it's bad 🙃
You should be able to run 95% of python projects locally
A dev container advocates the environment is the same between two machines and reduces the "works on my machine" syndromes. It's not bad. It's one tool of many to unify vastly varying dev environments.
IMO working in container is just a bad dev experience (at least for me)
All you usually need is to populate .env and set up dependencies
In a simply setup, yes that is where it starts.
A dev container is an actual standard which solves many problems. Running code is just one of them. It seems you are unaware of that. https://containers.dev/
Development containers documentation and specification page.
That's just not something I really need since it doesn't solve any problems for me
Everyone says that until they move to a new project and wish they made it ahead of time
I got some Java for you to write. Are you set up for it?
I don't write java 😃
I think the general topic was a wide scale development challenge.
So, no
Are your linters set up to automaticaly run and match the CI
Do you have the URLs to production logs?
We have some tools that help with managing distributed tasks. Do you have that set up too?
kind of see where this is going?
Our linters match the CI, and I don't really get the other points you're trying to make
I can walk to the grocery store but a car is faster. Does that mean I have no need for a car?
Your configuration is completely static and never changes?
We run a set of linters, if that set is changed I can add new one into CI, configuration is stored in pyproject.toml
You can run linters locally via single command
[tool.pdm.scripts]
lint = {composite = [
"black .",
"ruff . --fix",
"mypy .",
]}
This whole setup could be specific to my team, I have no idea
But I get paid enough not to care lol
I would say there's definitely a way to step through the code that I don't know about - most of the work I've done was in another project that I didn't find the need to do that and I only recently started the one I mentioned the code of before
You might be paid a lot more if you fix the company so devs can get shit done and be way more efficient 🤣
Don't get me wrong, I am going to research it more and see why things are the way there are
I'm fairly certain that there are ways to step through code among many other things, but despite being 6 months in I'm still considered extremely new in terms of how much I know about the tools and such
First 3 months were dedicated entirely to training and learning stuff and I'm still nowhere near knowledgeable enough on things here
Anyways lets steer back to the channel topic
I am thinking to give a learning session on pytest.
What do you guys think are the topic that needs to be included for that??
Any suggestions please???
Writing small, simple tests.
Hey all, can someone help me write tests for celery tasks that are started from fastapi requests in a docker container
Ma
Can you not use pdb or breakpoint()?
Have not tried but I'll look into it on Monday
Hey 2 part question,
I have a file tree like below.
I tried pytest -q --capture=no , but the functions in test_donation_functions.py +test_register_functions.py do not print.
How do I print in the files mentioned above?
│ ├───tests
│ │ │ models.py
│ │ │ __init__.py
│ │ │
│ │ ├───donations_tests
│ │ │ │ conftest.py
│ │ │ │ test_donation_functions.py
│ │ │ │ __init__.py
│ │ │ │
│ │ │
│ │ │
│ │ │
│ │ ├───non_db_functions
│ │ │ │ conftest.py
│ │ │ │ test_models.py
│ │ │ │ test_password_function.py
│ │ │ │ test_routes.py
│ │ │ │ __init__.py
│ │ │ │
│ │ │
│ │ ├───register_tests
│ │ │ │ conftest.py
│ │ │ │ test_register_functions.py
│ │ │ │ __init__.py
│ │ │ │
Also will the print statement show up in the example below. I realize below is just a simple example but my question still stands.
Thanks for the help.
def test_some_function():
print('some string')
assert 1 == 2
By functions you mean tests? How did you name them?
@viscid basalt
test_...
Yes I mean tests instead of functions I wasn't aware of the terminology
Terminology isn't a problem here, I think pytest should discover them 🤔
Run pytest -vv and check if these tests are running?
Sorry they discover them but I want the print statements to run
in the different tests
pytest -q --capture=no , I tried
just some extra info so if the functions work print('function works ') else print('function does not works ') This would be in if or else statement.
Its not essential but it is nice if it works
it was working when I had one conftest.py file
You don't really need to do what during tests
So you think don't worry about it?
If you need to add some extra info to your asserts you can add comma and a string:
assert func() == 42, "Should be equal to 42"
Ya I guess that works thanks
But really - prints should work
Can you create a minimal reproducable example (mro)?
I think it is easier if I link my github , it is getting late I will do it tomorrow do you mind if I at your name tomorrow here?
Sure
@viscid basalt My mistake it seems to be printing
how does testing in async work?
There are pytest plugins that allow you to write async tests
like anyio or pytest-asyncio
Hey folks. I can't wrap my head around the usage of 'class' scoped pytest fixtures. Assume I have a pytest fixture that is having the class scope. I also have a few test methods as well grouped under a class. So if I need to use this class based fixture, do I need to pass it as a parameter to each and every test in that class? Or should I just add the usefixtures('fixt_name') above the class name and continue working?
If former is the case, then would the class scoped fixture be called each time, the test runs? In that case wouldn't the definition of class scoped fixture - will run only once per class, be broken?
@pytest.fixture(scope='class')
def class_fixt():
pass
Should I use the class fixture this way ::
class ABC:
def test_1(self, class_fixt):
pass
def test_2(self, class_fixt):
pass
or
@pytest.mark.usefixtures("class_fixt")
class ABC:
def test_1(self):
pass
def test_2(self):
pass
a little more context might help - like do more classes use that fixture, and do you just want ot to execute surrounding tests or do you need the data in a nice manner
usefixtures can be fine, but sometimes all you need is a class scope fixture defined in the class using autouse
Oh sorry. So I am basically trying to initialise a Redis cache connection in the fixture, and in my tests I would be getting and setting data into Redis.
And, no not many classes use that fixture.
bascially if the fixture yields a object you directly use - its considered good practce to take it as a parameter and use it so its easy to see where things are from
But then, it would be called everytime a test runs and the meaning of classscoped ficture would be lost right?
fixture with class scope get cached at class scope, so it gets made once for all the tests that use it and belong to the right scope/parameter set
and for example if you have a class scope fixture with params, then pytest reorders the tests so it can hold onto it as long as sensible
so fixture scopes allow caching, and reorder tests to make effective use of those caches
Basically, I am not tied to keeping it as a class scoped fixture. But I wanted to know if there were any difference in passing the fixture as parameter to all the tests in that class and if i just declare it with usefixture(fixt_name) on top of the class without passing it to each test as params.
there shoudlnt be - usefixture is basically pretending the test had a parameter to ensure the fixture is used for it
however make sure that fixtures dont do magic actions at a distance that depend on one another without having the fixtures also depend on one another
Oh okay, so that means even if I use a class scoped fixture as a parameter to every test in a class, the fixture would actually only run once, and all those tests share the already run instance.
So in my above code snippet, I can use the class scoped fixture in both the ways right?
correct
I have a pytest plugin that is implemented as a class. Is there a way to use that plugin from the command line?
The documentation only covers plugins as modules
Apart from invoking pytest.main directly (which doesn't seem to interact well with coverage), I've managed to achieve it via this:
# conftest.py
plugin = MyPlugin()
pytest_addoption = plugin.pytest_addoption
pytest_sessionstart = plugin.pytest_sessionstart
pytest_sessionfinish = plugin.pytest_sessionfinish
but having to assign the attributes manually is not very DRY
Ideally, I would be able to just pass the plugin directly into pytest_plugins:
# conftest.py
pytest_plugins = [MyPlugin()]
but that doesn't work.
I've also tried referring to a local variable, like this:
# conftest.py
pytest_plugins = ['plugin']
plugin = MyPlugin()
which also fails.
the only way to safely do this would be to register the instance in the pytest_plugin_registred hook of a early conftest
its painfull7error prone to implement plugins that do addoption/configure as class
instead have have configure/addoption at a module level and the class implementing the details be registred in pytest_configure
I see, thanks for the info
PS,the builtin junitxml plugin is a example of that pattern, same goes for --last-failed
Not sure whether I'm doing something wrong here, but the Hypothesis strategies generated by this helper class often break the data_too_large health check. Can someone take a look, if they have time?
!pastebin
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the floppy disk icon in the top right, or by typing ctrl + S. After doing that, the URL should change. Copy the URL and post it here so others can see it.
(st is shorthand for the import from hypothesis import strategies as st, the rest are available in the standard library and carry their usual meanings)
Example usage:
@dataclass
class Account:
username: str # Should be between 4 and 31 chars
password: str # Should be between 4 and 31 chars
st_account_attrs = AttrsStrategyBuilder(Account)
@st_account_attrs.register('username', unique=True, required=True)
def st_username():
return st.text(min_size=4, max_size=31)
@st_account_attrs.register('password', required=True)
def st_password():
return st.text(min_size=4, max_size=31)
st_account = st_account_attrs().map(lambda attrs: Account(**attrs))
Is there's a way in unittest module, if i want to just test
def test_instance_creation (self):
x = SomeClass(...)
That will check that no exception was raised.
but you might want some assertions about x
Cant think of reasonable assertion
Maybe you don't need a test then?
The class init contained a param which requires some validation object and that object had decorator over it which was too complex for me to go over and over again.
Yeah i don't need a test for it, i just ended up making another test case for that validator object.
I'm looking to improve my company's testing and could use some advice/direction. It's Django, so it's using unittest. Right now, it's a mess. Data is added to the db in nearly every test suites setUpTestData, so often we end up with tests that have to account for other tests data, making it really hard to run clean tests.
At a previous company, they used factories to setup all the data as a separate step, but I'm not sure what was done at the end of the tests to bring the database back to its original state.
I'd love some advice on how to tackle this, or what to look for. We've got a lot of models, so creating all those factories right off the get-go is going to be impossible (it makes for a good longer term goal). I'm trying to see if there's some way to run all the tests (or each test) as a transaction with rollback, so no test affects another one. This is where things get confusing, because from documentation, it seems like tests are already isolated, but that doesn't seem to be the case for data saved to the DB, which make sense. I'd want a rollback between each test if it's a transaction.
Am I missing something/not understanding something? How can I, and then my company, build better large scale test suites.
Pytest, pytest-django. Use pytest fixtures. Maybe with something like factoryboy.
Yah, we're using mimesis for factories, but how will switching to pytest solve the transaction issue? This feels more of a structural thing than necessarily the package?
Pytest-django and pytest fixtures makes this all basically work correctly out of the box.
pytest fixtures is a very easy to use, nice abstraction to reuse code between tests and they are declared as standalone functions. way cleaner stuff than setup functions.
they can be chained to each other (in whatever desired proportion)
and they have granularity/scope choosable when to be invoked, once for every tests / for every module / once for testing session
that makes it highly optimizable to have the right amount of cleansing between tests for each stuff / with necessary level of reusage to keep performance up
at the same time pytest-django by default, makes sure that all database migrations are run only once for invoked testing process.
when i switch to another programming language, i immediately starting to miss lack of pytest in another language X 😆
factoryboy makes it even more powerful boilerplated and shorter in terms of unit testing code in the way that we have only the most relevant to unit test stuff to be present. highly promotes DRY setups regarding db testing and decreased noises from not important actions
I'm having trouble getting pytests to recognize the module that I'm testing
My tests are in a separate directory from the module I'm trying to test, which I believe is normal, but that appears to be making it impossible for it to recognize the module I'm testing
What is the error? What does the directory structure look like? How are you importing what you are testing?
The error is that a function (which I know exists in the .py file in the package I imported) isn't recognized. The top of my tests.py file is:
`import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(file), '..', 'src')))
from SwimScraper import *
print(SwimScraper)
def test_function():
df = getCollegeTeams(team_names = ['University of Pittsburgh', 'University of Louisville'])
assert len(df) > 0`
Whoops sorry
print(SwimScraper) prints the path to init.py in the correct directory. But when I run pytest SwimScraper/tests/tests.py , I get the following error: FAILED SwimScraper/tests/tests.py::test_function - NameError: name 'getCollegeTeams' is not defined. That function, and other functions I'd like to test, are in the in a file called SwimScraper.py that is in the same level of the init.py in the directory I'm importing
tests are in a separate directory from the source code. Here's the tree:
C:. ├───.pytest_cache │ └───v │ └───cache ├───build │ ├───bdist.win-amd64 │ └───lib │ └───SwimScraper ├───dist ├───src │ ├───SwimScraper │ │ └───__pycache__ │ └───SwimScraper.egg-info ├───tests │ ├───.pytest_cache │ │ └───v │ │ └───cache │ └───__pycache__ └───__pycache__
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')))
This is asking for issues. Don't add src to the python path. Install the package you're building with pip -e . so that it's an editible install. No path muckier needed.
Star * imports are difficult to visualize what's being imported, try explictly importing what you are testing.
pip -e?
-e, --editable <path/url> Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url.
If you install it into site-packages, imports "just work".
That's one of the points of the src/ nesting. To force you to test against an installed version.
Oh, OK. So I rerun pip -e each time I've made a change I want to test?
No. The install is symlinked to your actual files. You change the files, the installed version is updated.
hence the --editable
OK. It goes into my virtual environment I assume?
Yes. I assumed you were using one, I'm a little tired.
Works the same at a system level, just... at a system level.
venvs are better for cleanup.
Right, OK. Does it matter that my setup.cfg file is in the directory that countains src and tests and build
Oh... I see how this all happened now. Thanks a ton!
I am getting a error and I don't know how to fix the code. Can someone help? Also is there is a better way to test the code.
Here is the code https://paste.pythondiscord.com/4SQQ .
Please ping on reply.
AttributeError: 'SubRequest' object has no attribute 'params'
what is a SubRequest?
from ..models import UserTest, db I highly recommend absolute imports
Hm... Now I'm getting a module not found error. pip install -e . ran as expected. If I use python in my project, the statement import SwimScraper works as expected
pytest or python -m pytest?
pytest
try the other one
I think python -m pytest needs a file ending in _test.py to run properly, right?
nope
they are the same, except they handle python path slightly differently. Which is imo very stupid, but it's probably a big breaking change to fix that now.
Well, I get the same error
yeaok. Worth a shot. Personally I don't like the src dir idea because of problems like this...
But it has other advantages I'm told.. just can't remember what they are right now :P
OK, now I'm going crazy. It worked... once. Then stopped working. argh
Does pytest run tests in paralell?
not by default no, but you can get that with xdist... but the overhead it quite severe so you need quite a slow test suite to make it worth it
better to look at something like testmon
@proud nebula
"What is a SubRequest?" I have no idea.
When I run the code by typing pytest -q --capture=no I get the error
=========================================================== ERRORS ===========================================================
_______________________________________________ ERROR collecting test session ________________________________________________
..\..\..\..\Anaconda3\envs\py\lib\importlib\__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1050: in _gcd_import
???
<frozen importlib._bootstrap>:1027: in _find_and_load
???
<frozen importlib._bootstrap>:1006: in _find_and_load_unlocked
???
<frozen importlib._bootstrap>:688: in _load_unlocked
???
..\..\..\..\Anaconda3\envs\py\lib\site-packages\_pytest\assertion\rewrite.py:168: in exec_module
exec(co, module.__dict__)
app\tests\login_tests\conftest.py:9: in <module>
from tests.models import UserTest, db
E ModuleNotFoundError: No module named 'tests'
================================================== short test summary info ===================================================
ERROR - ModuleNotFoundError: No module named 'tests'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 error in 1.81s
Here is my file tree.
Please ping on reply.
That's just you failing to run the tests at all. That's a step backwards.
@proud nebula You are correct. I forgot to go from app.tests.models ... it seems to solve it and leave me with the original error
Why do you think there should be a "params" member on the request object?
username_or_email = request.params seems like a weird line too... it makes no sense. It has singular on the left and plural (maybe a dict even?) on the right
username_form has a weird name too, it's not a form, but I guess it should be username_for_form?
Should I be using logging? I need to view different variables to see why my tests in pytest are failing. I guess using print statements is not a normal thing for that?
Use a debugger?
It's probably time to learn... Can you assert that there's an exception with pytest?
with raises(YourException):
@proud nebula
Here is the example I based the code on.
https://stackoverflow.com/questions/35413134/what-does-indirect-true-false-in-pytest-mark-parametrize-do-mean
Here is another example should I be using a class like the example below?
https://stackoverflow.com/questions/58319619/pytest-request-param-of-fixture-to-be-used-in-tests
I found this about the error, "AttributeError: SubRequest instance has no attribute 'param' "
https://github.com/pytest-dev/pytest-repeat/issues/2
But I already added autouse=True. How do I fix this?
Please ping on reply . Thanks for the responses
I just want to understand what does it mean or what happens if I set indirect parameter to True or False in the pytest.mark.parametrize?
I have parameterized my fixture to call APIs, with different input data to POST request on each call with scope as class. Since I need to check API response with sent data. I need to read request p...
param and params are not the same.
Tests are like magic. I don't know why I didn't learn about this earlier
Magic? They are what you do at the terminal to test your code except they are automated.
@proud nebula or anyone willing to respond , sorry to be a bother. I am wondering if I have to turn the code into a class.
Here is the example I am using https://stackoverflow.com/questions/35413134/what-does-indirect-true-false-in-pytest-mark-parametrize-do-mean
request = <SubRequest 'username_or_email' for <Function test_login_page_get>>
@pytest.fixture
def username_or_email(request):
> return request.param # username_form or email_form
E AttributeError: 'SubRequest' object has no attribute 'param'
app\tests\login_tests\conftest.py:89: AttributeError
The code clearer doesn't have param attribute , but in the example they don't have param anywhere except in one location. Any advice?
Again; what do you think "request" is? Your code seems like random banging on keyboard. Not like you're thinking.
Thanks for the help. I just about got it running. I looked at the documentation for pytest specifically "request" and that helped a lot. I should have done that from the start .
Is there a way to print "live" messages in pytest? As an example, I am using git lfs to store big data files used in regression tests. Since some of my colleagues are not experienced with git lfs, I wanted to automated it with a fixture. If the files are not present, pull them from git lfs.
However, if this happens, it will take longer the first time. Is there a way to indicate this when happening? Just so they are aware what's happeninf
running pytest with -s flag makes messages printed in real time
kind of floody though
otherwise u can always write script wrapper around pytest
https://taskfile.dev/ recommending taskfile.dev for that
cross platform solution with nice interface
u can forward all additional custom pytest args automatically into it
I will take a look at these. Thanks! 🙂
Hey, I have a feeling this is messy code, but it doesn't make sense to separate it into multiple methods: https://pst.moe/paste/ezyrxr
u can add FactoryBoy to decrease noise in tests with not important code
Also you can rewrite it with pytest, to have user logged in, into reusable fixture
hello everyone
Hi, I'm using python requests third party module to perform http calls to an external API. This API require an authentication so I'm using a class that implements this authentication based on requests.auth.AuthBase. This means that custom Auth class does a request to retrieve a token and then the actual call performs another request. I'm using requests.Session in both cases. For unit testing I use pytest and I'm creating mock objects using monkeypatch to avoid calling the actual API. My problem is when I'm creating unit tests for functionalities that depends on this call, I need to monkeypatch two requests.Session since they are in separate modules. It seems like monkeypatch override the last object I try to mock. So I have something like this
monkeypatch.setattr("client.requests.Session", client_requests_fail_mock)```
and inside `utils` module, the mocked `requests.Session` is actually the one from `client`, which is undesired. Any idea how can I avoid overriding mocked objects? Also, I'd like to stick to `monkeypatch` instead of using `unittest` module
basically, utils.requests.Session is behaving as client_requests_fail_mock. If I switch monkeypatch statement order, behavior also switches
An alternative (that I usually prefer) is to wrap the requests call in a function, and monkey patch that one, instead of the actual requests library.
I see, and if you want to write test for that function? I know "there's not much to test there" but I'm pursuing 100% coverage
Then I guess you would need to mock the requests library. I’m very much pro TDD and unit testing, but don’t think 100% coverage will add much value (my opinion).
that's exactly what I'm trying to do (mock requests) library. I fully understand your opinion about 100% of coverage 🙂
If you would make the wrapper function generic, you could write a unit test for it, without the issues you described with auth and session? You would then have coverage for that function too. 😄
yeah, I don't see other way around. Thank you 🙂
Hello, how do I get the response from one unit test to another in order to do some operations on it? Is it possible to override default value of variable outside the unit tests in Pytest?
that's not ideal. Test should be isolated. If you want to use predefined data as input in a test you can use fixtures
Well, the problem is program is written in such way that when you generate an object, you get an id which you uses later on, I don't see any way to fully isolate tests
You can't pass an id as an argument when generating an object
grab the object ID and just statically put it in the second test. Would that satisfy requirements?
I guess, I'm pretty new to automated tests
How do I do that? Using fixtures or cache?
to grab the first object ID, I'd write the test and after you get the desired object, place a breakpoint() statement or debug somehow so you can grab the data you need. Then create the fixture for the second test
Okay, thanks a lot
That sounds like how all tests with fixtures work...
Maybe, like I said, I'm new to automated tests, all what I did was manual testing
normally you do something like:
@pytest.fixture
def foo():
return Foo.objects.create(bar=1)
def test_something(foo):
# here foo.pk will be whatever it is and you can use it
wsg @vast bobcat my mi
I am trying to redirect and test that redirect in functions in flask and pytest. I have 2 functions. redirect_function which I plan on testing and redirect_function2 which represent a longer function. I shortened redirect_function2 just for temporarily making it easier to test but the output will be the same in the longer function.
When I run the code below I am getting an error.
def redirect_function():
return redirect(url_for('auth.login'))
def redirect_function2():
return redirect(url_for('auth.login'))
def test_login_functions():
assert redirect_function() == redirect_function2()
E RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.
The error is a little longer but this is the gist.
Then when I add
from flask import redirect, url_for
def redirect_function():
return redirect(url_for('auth.login'))
def redirect_function2():
return redirect(url_for('auth.login'))
def test_login_functions():
#with test_app.test_request_context():
with test_app.test_request_context():
assert redirect_function() == redirect_function2()
Here is the error when I add with test_app.test_request_context(): in the example above.
test_app.test_request_context(): , is used for pytest instead of with test_app.test_request_context()
def test_login_functions():
#with test_app.test_request_context():
with test_app.test_request_context():
assert redirect_function() == redirect_function2()
E assert <Response 218 bytes [302 FOUND]> == <Response 218 bytes [302 FOUND]>
E + where <Response 218 bytes [302 FOUND]> = redirect_function()
E + and <Response 218 bytes [302 FOUND]> = redirect_function2()
app\tests\login_tests\test_login_functions.py:27: AssertionError
If anyone is curious I made a post here. https://www.reddit.com/r/flask/comments/152b634/in_pytest_and_flask_if_i_have_function_that/ .
Any idea how to fix the problem?
Does anyone have idea about unit testing in FastAPI, I need assistance.
There’s some info at the FastAPI docs:
thanks for this link @drifting sorrel but I read those, and problem is these are not sufficient for my need,
like I created API (using FastAPI) but don't have any idea about testing it