#unit-testing
1 messages Β· Page 2 of 1
this can be done as long as u properly... make isolated data inputs and outputs from your database class, well and properly isolate code logic.
input just lists of dataclasses, return another lists of databases
(Pydantic models are kind of perfect for this)
the rest of your code becomes not depended on your database code in any way... thus u can perfectly mock it away with the most simple mock returning yet another list of dataclasses)
I'm only looking how to specifically unit test the module which very specifically talk to the database
use MySQL raised locally then for this π don't mock it. Just be sure to have pointed with ENV variables / inserted config so that it would use your local MySQL instance
rest of the code has a layer over it
Yep, looks like I only initialize my config with the connection values like localhost:3306 and then test
True!
If you want to talk about Hypothesis, @ me in this channel π
Anyone tried colocating their tests in the same file as the tested code? Howβd that work out for you?
Hello everybody, I'm here to discuss pytest, selenium, test scaling and stuff to find a new entertaining job
Any SDETs here?
scikit-learn does it. i'm not a fan, i prefer having a separate test directory, it makes project configuration easier. i don't see much benefit in keeping tests alongside source code.
One thing you can do is actually run your tests on import. Advantage: you can't not run your tests.
If dunder main should still work!
the idea is that you don't put it in such a guard
Has anyone encountered this weird pytest issue where environment variables are not available to tests if run from the root folder? i.e.
$ pytest func_test/test_f.py
runs successfully with all env variables but
$ pytest
does not
no, i don't think that's typical. can you reproduce in a clean directory with a trivial test file?
I'll try :/ Would a stackoverflow question help in the meantime?
So, I have my app structured like this:
container.py
class Container(containers.DeclarativeContainer):
wiring_config = containers.WiringConfiguration(modules=[".routes"])
print(...
i often end up answering my own questions (including on SO) in the process of attempting to construct a minimum working example
Let me do this right now, hopefully it'll help me out as well
enter obscure bugs which sometimes work and sometimes dont
well that's exactly why a MWE is so important
if you can't reproduce the error in the minimal example, then the problem must be in your own setup
you're right, I don't know what's wrong but my minimal setup works perfectly fine but NO IDEA what's wrong in my OG setup
Nah, I could reproduce the error!
Hey @low oyster!
It looks like you tried to attach file type(s) that we do not allow (.zip). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a, .csv, .json.
Feel free to ask in #community-meta if you think this is a mistake.
@pearl cliff can I DM you the MWE? The server's policies do not allow me to upload a zip to this channel
can't you upload them to a new git repo and share the link here?
i am in the middle of some stuff now so i won't be able to test it anyway
that way no one even has to download/unzip it to see the code
good idea - lemme do this
@potent quest @pearl cliff whenever you both get the chance - https://github.com/burgundypantone/pytest_issue
Thanks in advance π
what's the error it gives you?
I see - TypeError: 'NoneType' object is not subscriptable
Because, inside my container init code, it does not get ANY env vars π¦
what's the full traceback?
_______________________________________________________________ ERROR at setup of test_cool _______________________________________________________________
mock_settings_env_vars = None
@pytest.fixture(scope='module', autouse=True)
def app(mock_settings_env_vars):
# test if pytest fixture for env vars works as expected
assert os.environ["ENV"] == "TEST", f"ENV is set to {os.environ['ENV']}"
print(f"********* HIIIII ********* {os.environ['ENV']}")
from src import create_app
mock_db = MockDB(
os.environ["DB_USERNAME"],
os.environ["DB_PASSWORD"],
os.environ["DB_HOST"],
os.environ["DB_PORT"],
)
mock_db.setup()
> app = create_app()
functional_tests/test_functional.py:45:
...
functional_tests/test_functional.py:45:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../src/__init__.py:13: in create_app
container.init_resources()
src/dependency_injector/containers.pyx:343: in dependency_injector.containers.DynamicContainer.init_resources
???
src/dependency_injector/providers.pyx:3637: in dependency_injector.providers.Resource.init
???
src/dependency_injector/providers.pyx:215: in dependency_injector.providers.Provider.__call__
???
src/dependency_injector/providers.pyx:3740: in dependency_injector.providers.Resource._provide
???
src/dependency_injector/providers.pxd:582: in dependency_injector.providers.__call
???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <src.repository.db_repository.DBRepository object at 0x10ee96550>, config = None
def __init__(self, config: dict) -> None:
logging.debug(f"DBRepository.__init__(): initializing")
print(f"FROM ENV WE GOT - {os.environ.get('ENV')}")
self.config = config
print(f"*********\nconfig is {config}\n**********")
> conn_str = DBRepository.build_connection_str(**config["connection"])
E TypeError: 'NoneType' object is not subscriptable
../src/repository/db_repository.py:19: TypeError
it looks like the config object ended up being None somehow. hard to say why, without knowing more about your code.
yep! I verified it with the print statements - here's the code - https://github.com/burgundypantone/pytest_issue/blob/main/src/containers.py#L30
src/containers.py line 30
config.load(envs_required=True)```
That print() you see in the traceback above - it prints None
right, so your challenge now is figuring out why
at this point i would drop into a debugger and start exploring the local variables, moving up and down the call stack to see at what point the config ended up becoming None
sometimes you find that it was None all the way up to the top level, and you have to start looking elsewhere
try renaming conf/
pytest uses conf.py for config and i wonder if its getting confused
i always used conftest.py, does it also recognize conf.py?
I've done ALL of that - trust me, I've spent 2 hours looking thru it
In the function that JUST calls it, I added a debug print statement, that environment value is still available.
Right when it does an container.init_resources() it fails
only 2 hours? i've spent days debugging stuff before
is there a way using the module import unittest that I can make a test method not run unless another test runs, like a some sort of require functionality
hm, maybe i got confused with sphinx lol
oh yeah sphinx has conf.py (inexplicably in the docs source folder by default?)
i also couldn't figure out how the -c option worked, so i guess i'm stuck with docs/source/conf.py instead of docs/conf.py forever
wdym
i have a feeling it's a pytest bug?
My debugger doesn't "work" (i.e. doesn't stop at the breakpoints) probably because it's a part of a fixture
The commands recognized by the debugger are listed below. Most commands can be abbreviated to one or two letters as indicated; e.g. h(elp) means that either h or help can be used to enter the help command (but not he or hel, nor H or Help or HELP). Arguments to commands must be separated by whitespace (spaces or tabs). Optional arguments are enclosed in square brackets ([]) in the command syntax; the square brackets must not be typed. Alternatives in the command syntax are separated by a vertical bar (|).
Entering a blank line repeats the last command entered. Exception: if the last command was a list command, the next 11 lines are listed.
@potent quest @pearl cliff when I IGNORE a whole module of tests, I don't see the problem AT ALL
what was the problem again?
$ pytest doesn't correctly pass the environment variables
$ pytest functional_tests/ works as expected and even $pytest --ignore-glob=<other_test_module>
It's crazy!!
what happens when you set
[tool.pytest.ini_options]
testpaths = functional_tests/
and run pytest without any args?
something else must be going on
is one of your tests clearing the environment?
Not the environment, but just tearsdown the db
So, it's a VERY weird issue, because the env vars are available in the test up till a point and then when it enters some block of code, it doesn't get the env vars
All in the same test!
something happening with fixture cleanup?
Nope - fixture clean up happens athe end of the test
it's mid test when it suddenly disappears
I'm considering opening an issue with pytest
i am almost certain that pytest is not deleting your test database for you
i get the frustration though. it sounds like you have a fairly complicated setup
you'll have to keep "bisecting" so to speak
it's a very simple setup π¦
--> mock environment variables
--> Initialise application with said env vars (this is where it fails)
--> Test feature
are you able to share some of the relevant code?
i can't remember if you did already
Yep
@pearl cliff here you go - from the tests folder, run $ pytest -rA and you'll see the functional tests failing
can you add some logging or print in MockDB.teardown to see when the teardown is actually being run?
why do you have tests/__init__.py if you run pytest from inside the tests directory?
is the test database actually being torn down, or are the env vars simply not taking effect?
i see mock_settings_env_vars has module scope but app has session scope
that seems off to me
do you actually need those to be env vars at all? or are you just using them to set up the mock database?
I do! I need them to set up the mock db and they also help initialize the actual db connection the app
would that be the issue?
turns out I do need it π€
oh, sorry about this - i was just testing something and forgot to make it uniform - it should both be module
What would be a moderate way to test a method body and its variables?
depends on present code. Sometimes it is enough to use doctest if body code is fully.... functional and not requiring any prebaked complex data.
if u don't have any third party libs, people can resort to unittest written tests
and if it is fully fledged project, people go for pytest
I use pytest in this project, i just had bad lectures on software testing and trying to comprehend most of it
umm. In a nutshell this is a bit long to answer question. Different aspects of testing involves different Software Engineering skills... related books:
- Unit testing best practices and principles by Vladimir Khorikov gives general view and understanding of the process
- TDD by Kent Beck gives practical head on for devleopment from bottom
- Code Complete by McConnel gives understanding how to organize code/write/everything in the way it would be easier to test code
- Head First Design Patterns / End of TDD Kent Beck book, gives Design Patterns related to architecture / testing architecture
- Clean Architecture by Robert Martin gives view... of how clean architecture can be and showing how easier it can be testable because of that
- For backend stuff,
porto architectureis a nice in general design based on clean architecture to organize code
probably could be missing some link in it
OOP some book missing for full picture perhaps, partially its material is spreaded through the books though.
as u can see full understanding of testing is a long journey as learning code architecture, but u can be already testing just after one book / or diving head on into pytest
Thanks for recommending! π
Anyone have some tips for creating lots of test data? Especially when it's deeply nested, so direct construction of the objects quickly becomes a mess that looks like a mountain range π if you rotate it
do u have a lot of database objects for test data?
anyway... regardless what u have, recommending checking https://factoryboy.readthedocs.io/en/stable/ and their integration for Django ORM and SQLAlchemy.
they solved creating nested data in a nice way too
even without integrations, they have pretty much cool approach
for any nested objects, we just reuse already created TestFactory object creator
creating a lot of data is also solved with batch/bulk creations
Database integrations make sure that objects are created in db at the moment of a class init, including all its nested dependencies
nope, imagine just a ton of dataclasses
and ideally I'd like to avoid adding extra libraries
I guess the issue isn't the volume of the data, but like... the syntactic noise
all the kwargs, enum paths, class names etc.
Check factory boy anyway to learn their pattern
It is very well. For our very big projects it solves issue
Also it uses fakery under hood to generate fake data
Which u could find useful too
During object creation we override explicitly only needed fields to be certain. The rest is random faked away automatically
Makes only necessary code checked in test
π€ sounds like hypothesis with extra steps
Factory boy creates test factories declared once for one object type and makes it reusable across all tests
Or reusable for nested situations in other test factories
I'm ok with specifying the data, in fact it's important what data it is. I'm asking more about removing the noise. Like, suppose you have:
program = prog.Program(
title="My Super Program",
description=None,
sections=[
prog.Section(
title="Amazing Section",
definitions=[],
kind=prog.SectionKind.REMOTE,
),
prog.Section(
title="Even Better Section",
definitions=[
prog.Option(
name="UNLADEN_SWALLOW_AIRSPEED_VELOCITY",
options=prog.Options({"AFRICAN", "EUROPEAN"}),
datatype=prog.DataType.FLOATING,
raw_value=3.14,
)
],
kind=prog.SectionKind.LOCAL,
),
],
)
the actual "data" here is ```
"My Super Program":
remote "Amazing Section":
pass
local "Even Better Section":
UNLADEN_SWALLOW_AIRSPEED_VELOCITY {"AFRICAN", "EUROPEAN") : float = 3.14
I guess what I'm asking is: how can I make a DSL for such data definitions without the massive overhead of actually making one and then learning it as a reader of the code?
cc@maiden pawn
When I will reach PC, I ll write code example
Hi, I wanted to ask how would one unittest a binary tree? So far when testing I've been testing code against an expected value that I know is the correct output but I believe this method doesn't work for testing a binary tree
fakery = fakery.generator()
# TEST FACTORIES
def OptionsTestFactory(**kwargs) -> prog.Options:
return prog.Options(
fakery.random_set(value_generator=fakery.name(), min_values=1, max_values=3)
)
def OptionTestFactory(**kwargs) -> prog.Option:
return prog.Option(
name=kwargs.get("name", fakery.name()),
options=fakery.random_array(min_values=1, max_values=3, value_generator=OptionsTestFactory),
datatype=fakery.choices(prog.DataType.FLOATING),
raw_value=kwargs.get("raw_value", fakery.float()),
)
def SectionTestFactory(**kwargs) -> prog.Section:
return prog.Section(
title=kwargs.get("title", fakery.name()),
definitions=[
fakery.random_array(min_values=1, max_values=3, value_generator=OptionTestFactory),
],
kind=kwargs.get(
"kind",
fakery.choices(prog.SectionKind.REMOTE, prog.SectionKind.LOCAL) # if such concept does not exist, create new sub Test Factory for them
),
),
def ProgramTestFactory(**kwargs) -> prog.Program:
return prog.Program(
title=kwargs.get("name", fakery.name()),
description=kwargs.get("description", fakery.name()),
sections=fakery.random_array(min_values=1, max_values=3, value_generator=SectionTestFactory),
)
# TESTS
def test_title_of_program():
title = "My Super Program"
program = ProgramTestFactory(title=title)
assert program.title == title
def test_section_titles():
section_title = "Amazing Section"
section = SectionTestFactory(title="section_title")
program = ProgramTestFactory(sections=[section])
assert program.section[0].title == section_title
def test_options_in_sections():
options = OptionsTestFactory({"AFRICAN", "EUROPEAN"})
option = OptionTestFactory(options=options)
section = SectionTestFactory(definitions=[option])
assert Whatever_u_want = True, u get the idea
a bit of pseudocode in python style
the idea is next one. One time writing test factories, and reusing in tests and in nested object creations
in tests u declare only objects u wish to be certain in values, the rest is generated with fake values randomly
it makes sure u test in tests them only with logic u really wish to check
minimal readable tests in results
if it is important only them having correct options for certain test, in order for some code to succeed? then only options are declared in a test. the rest is faked randomly automatically with our Test Factories
all coresponding nested values are created automatically π if they aren't declared
How does that help me represent the data here?
<#unit-testing message>
I don't need to generate it, I just want to write it down concisely, with as little noise as possible
I am confused what u a wishing to achieve then
clear typing structure of dataclass?
I want this
<#unit-testing message>
to look more like this in code:
"My Super Program":
remote "Amazing Section":
pass
local "Even Better Section":
UNLADEN_SWALLOW_AIRSPEED_VELOCITY {"AFRICAN", "EUROPEAN") : float = 3.14
``` and less like assembly or something.
without adding a lot of extra setup
this is not valid python code, could u explain it in python terms? 
like... I want to reduce the amount of noise, given that these objects will share a lot of boilerplate
it just looks messy, and it's very hard to read.
amount of noise for what?
i don't get your goal
provide expected usage case
I mean "noise' as in "signal-to-noise ration". For example, a hello, world! program has a high SNR in Python and a low SNR in Java, because in Java you need to build "scaffolding" or "noise" around the stuff actually interesting for the domain, the "signal", the information you're trying to convey.
That long snippet is mostly scaffolding -- keyword arguments, class names, paths, various brackets, etc.
The "data" -- i.e. the values I want to vary, is pretty small:
1.
a "My Super Program" with two sections:
- empty remote "Amazing Section"
- local "Even Better Section" with one definition:
UNLADEN_SWALLOW_AIRSPEED_VELOCITY {"AFRICAN", "EUROPEAN") : float = 3.14
2.
a "My Super Program 2" with two sections:
- empty local "Amazing Section"
- empty local "Even Better Section 2":
So, u wish what? creating those two programs with minimal code footprint to init?
yes, I want a concise way of specifying such structures
why not just using dataclasses or better pydantic models then? 
what do they not have for you?
I am using dataclasses here, and this is what it looks like
This is a trivial amount of data, with something more complex and interesting it will span many screens
so I want a more compact notation for instantiating such nested values
okay, u declared in code datatype=prog.DataType.FLOATING,
but u said that this data is not important at all for your data that has meaning
a "My Super Program" with two sections:
- empty remote "Amazing Section"
- local "Even Better Section" with one definition:
UNLADEN_SWALLOW_AIRSPEED_VELOCITY {"AFRICAN", "EUROPEAN") : float = 3.14
when is it supposed to be set then?
Well, I'm not literally suggesting this syntax
okay.
just as an example of something more concise
Extracting helper functions for some common patterns seems to work somewhat, but not always
and making it convenient makes the helper functions more and more complicated, probably requiring their own tests
Well, to be honest only yaml syntax comes to mind.
and that u can read it with parser
and using in some factory to init your class
u a literally writing me almost yaml syntax above after all
I guess that is possible. The program already has a parser for this structure actually
one issue is that I'd like to test the parser separately, but if it's just for convenience of testing another module, I guess it's not bad
at this point I think I'm looking for a problem to a solution
another thing that nobody will write like that because
using yaml, u a giving up IDE and language functionality
which would be preferable to have over some signal to noise ratio
automatic validation at language level matters
when u use just dataclasses, u can validate a lot with automatic linters, including static type checkers like mypy
The only thing people would preferable fix....
instead of writing in nested way to keep it at the left of a code text
first creating options, then object option
and then assigning everything to section, and section to program
in this way they will be all in sequence at the left of a code. right after each other
and that would be enough for happiness to avoid nestiness
====
complex creations should be solved with creational design patterns π
plus if u are that woried about noises.
U can replace imports
instead of
import prog
importing
from prog import Program, Section, Option, Options, DataType, SectionKind
it will eliminate already huge amount of them
Well, this is test data. If it fails at runtime, it is immediately clear
That would still span screens of code. I guess there's less visual nesting though
create a factory satisfying minimalistic syntax u need to have them created then. Factory could be not requiring from you using keywords, or using shorter keywords
Yeah that's what I did with helper functions
I guess I'm just tired of everything... And it's not a problem with test data
if this factory is intended for working code, it can be part of your dataclass like
@dataclass
class Option:
abc = 123
@classmethod
def factory_name(cls, args):
return cls(
*args = args
)
if this factory is intended for testing code only, keep factory creating in code where tests are located
i can relate to that. I have finished working day, and after handling some more tasks i need to find time for self studies in addition
wishing only to die and to sleep
no like... globally
I stare at code and it's not registering to me
also it doesn't help that I'm browsing discord at 2:30 π
well, that feels like amount of... tiredness beyond the levels i usually experienced.
anyway, walk outside sounds like a good thing
may be even taking a vacation xD
going to try tomorrow walking with backpack of weight. and making records in my fitness band Huawei Honor
well, that's why better to do it from morning
although paper sprey can be carried at any age xD
anyway... unit testing
more like a sleep. I can recommend having sleeping mask is awesome
helps to sleep better for people... who u know, having messy day/night schedule
I'll be waiting for the second sun to wake me up π«
is this sarcastic or no
Maybe cleaning your monitor will help?
unittest has been built into the Python standard library since version 2.1
Here you are computing the number of "good" values in the x list. The list consists of tuples, so it's always going to be zero.
Giving variables better names makes you more likely to write correct code.
Also, why are you comparing to the built-in max function? What is your goal here?
Anyway, I recommend checking out #βο½how-to-get-help and claiming a help channel.
And please post code as text π
i have no idea, this is a weird issue. but you should not need it
btw i haven't been able to figure out what's going on in your situation, i'm sorry to say
i hope the debugging goes well
i just spet a week debugging my own work if that make syou feel any better
@pearl cliff I'm no longer chasing it - it just doesn't make sense! But thank you so so much for all your help π
@fiery arrow here question is how can we check the adj containing good and bad ,if good is maximum then print nice index
I had not considered Hypothesis when I started thinking about https://vitrina.readthedocs.io/en/latest/howto/consume.html
and as I get deeper into the use case, I think it might be perfect.
Do you know if it can produce output for HTML report formatters like Allure, or am I thinking of this wrong way?
Yes, I find the path thing annoying. It's actually not as confusing once you figure out how you are launching sphinx-build ...
if you're using make html, then
most of the default Makefile pass the source/ path to shpinx-build so, it will assume that conf.py is in source/
You can edit your make file to handle that differently and then you might have to update your conf.py file because it assumes that the path is ./ .
@pearl cliff , feel free to DM me if you ever want to figure out Sphinx stuff. I'm kind of a Sphinx fanboy and happy to track down obscure tricks.
the -c option provides a directory relative to the source directory, not the current working directory?
like I said.... it's annoying.
If you're using sphinx-build -h html -o _build -c .
and not the Makefile
then -c will apply to the current directory. If the conf.py is there, it will execute and assume all paths to be relative to conf.py.
i'm calling sphinx-build -M from my own makefile. let me post, give me a min
i'm using -M because i didn't want to figure out the make dependency and pattern matching stuff when sphinx-build already does it π
I don't blame you π
my main problem is that i'm using sphinx-apidoc to generate rst source files
so i'd have to have something like stage1.mk and stage2.mk if i wanted to do it all in Make itself
That's ok. Yes it's a 2 stage process, but that can be addressed.
# Fallback values for variables inherited from top-level Makefile
SPHINXBUILD ?= ../.venv/bin/sphinx-build
SPHINXOPTS ?= -W
DOC_SOURCEDIR = ./source
DOC_BUILDDIR = ./build
.PHONY: clean
clean:
$(SPHINXBUILD) -M $@ "$(DOC_SOURCEDIR)" "$(DOC_BUILDDIR)" $(SPHINXOPTS)
-rm -rf ./source/api/_autosummary
-rm -rf ./source/_api
.PHONY: html
html: source/_api/tive.rst
$(SPHINXBUILD) -M $@ "$(DOC_SOURCEDIR)" "$(DOC_BUILDDIR)" $(SPHINXOPTS)
source/_api/%.rst: $(PYTHON_SOURCES)
../.venv/bin/sphinx-apidoc \
--force \
--no-toc \
--separate \
--implicit-namespaces \
--maxdepth 2 \
--module-first \
--templatedir source/_templates \
--output-dir source/_api \
$(PY_TOPLEVEL)
this is in docs/Makefile -- i wanted to move conf.py to docs/ instead of docs/source
So, it's possible to have one make target lead to another and run make only once. But there may be a better way.
ok, try:
DOC_SOURCEDIR = ./
no problem
i was hoping to just set -c . but that didn't work, it couldn't find the conf.py anymore
put the conf.py in ./ and then inside conf.py you wante to add another path to search
or -c conf.py, i don't remember whether it's a directory or filename
sys.path.insert(0, os.path.abspath('../src'))
or, I guess sys.path.insert(0, os.path.abspath('./source'))\
in your case
and forget the -c option
( @pearl cliff , do you want to hop on a call ?)
this is the source dir for rst source files, not python source files
i can't join a call now, sorry
thank you for offering though!
give me a moment, i need to fix some things in my setup anyway. i'll post a more complete example to github as a gist if you want to look over it when i'm done
Ok, so it's still possible, but a bit trickier.
SGTM, I'm not employed right now, so I'm flexible.
Sphinx can be a PITA if you don't do it a lot, but once you have it dialed in, it's pretty sweet.
this i think is the last thing i haven't "dialed in" yet π
frankly i am not much of a fan of rst and i'd pay good money for a sphinx extension that reads asciidoc instead. sphinx itself is great (albeit a little clunky)
also to be clear, my current arrangement (which is the default using sphinx-quickstart) is:
./
Makefile
docs/
Makefile
source/
conf.py
index.rst
_api/**/*.rst
build/
html/*
source/**/*.py
test/**/*.py
If you want to publish it on readthedocs.io there are a few tricks I can show you.
this is for my company so i have no need for that currently, although an internal readthedocs deployment could be cool π
and just so you can see what i want to achieve, i just want to move conf.py from docs/source/conf.py to docs/conf.py:
./
Makefile
docs/
Makefile
conf.py
source/
index.rst
_api/**/*.rst
build/
html/*
source/**/*.py
test/**/*.py
....and that's how I came to learn all this stuff, I used to maintain a private instance at my old job
not for any reason other than "i think it makes more sense there"
ok... and when you run make it's using the Makefile in ./docs/ not the one in ./ ?
So, about apidoc... IIRC, it's going to compile your modules and right out some boilerplate rst to some path.
on the next pass, Sphinx will read that rst and then compile the code to provide the missing details.
It's almost less painful to come up with your own skeleton rst and skip the apidoc stage every single build.
btw the requests library (and many others) operate this way.
yes. my top-level makefile has:
.PHONY: build-docs
build-docs:
$(MAKE) -C docs html
which is equivalent to cd docs && make html
yeah, sphinx is intended for "hand-crafted" documentation like this. i don't mind that apidoc is "bolted on", but it does split the docs build into two stages which is a little annoying
i'll probably want to tinker with it more in the future, but for now this does the job well enough
this codebase is going to be added to by lots of people who aren't necessarily strong developers, so i'd like them to not have to write a custom rst doc file if possible
Ooooh, ok, in that case, there are a few options to consider.
Create simple index.rst page that has a number of .. include:: file.md (assuming they like to write markdown)
and then folks can compose and edit, as long as they save to the right place.
If you want to really make it idiot proof, you could create two "stages" and refer to both of them from the make file...
eg. stage_prep reaad some jina templates and pull in whatever boilerplate text or rst.... even run apidoc if need be
stage_build will then create the HTML from the rst sources
i'd rather auto-generate from docstrings, but i didn't know sphinx could read markdown
anyway this is #unit-testing ,we should probably move to #tools-and-devops π
I don't understand what you're trying to do, but Hypothesis gives you a way to write better test functions - it's (more) like pytest parameterize, not the pytest test runner. HTML output would usually be a concern for the latter.
Thank you @royal orbit , that makes so much sense!
If you run Hypothesis tests using pytest, pytest-allure does work for example
@pearl cliff I move this to #tools-and-devops message
hi
Hi,
I am sorry for very basic question.
I have experience in python and pytest, but have not used moto to test AWS service. Currently, I want to write test for AWS SecretManager to fetch test. Is their any resource/links where I can gear up quickly. Currently going through Doc of moto. Thanks.
Hi, I have problems with unreliable hypothesis tests. Basically I have hundreds of tests and about 20-30% of the time CI fails as one of the tests errors after exceeding hypothesis deadline (this happens sometimes also on my PC so it is not connected with the CI server). This happens on random tests - some more often than others. When I try using the test data generated by hypothesis that made the test exceed the deadline then the test is running in like 2-3ms (deadline is 200). I am using the newest hypothesis version, tried downgrading by one major version but this still happens. Does anybody know what could be the reason? It is quite hard to reproduce as it is not deterministic behavior and happens on different tests (I've tried to make an example test similar to one of the failing tests and run it like few hundred times using bash script and it did not fail once). Is it maybe possible to disable deadline without decorating every test? (Some tests are not that complex - for example hypothesis is used to generate 2 UUIDs) | edit: Managed to "fix" it by creating custom profile with deadline=None (although the root cause still exists)
maybe set print_blob = True so you can try to reproduce the test when it fails on your own machine? you might have some kind of pathological case in your code. hypothesis itself doesn't seem to have performance problems, i only ever encounter deadline failures when i write slow bad tests and/or slow bad code
Common causes of 100x performance variations include your VM or process has a 'noisy neighbour' and was arbitrarily slow (common on free CI services), or a cache miss forcing rare but slow computation. If it sometimes happens on your machine I'd guess the latter.
Using a settings profile to set deadline=None seems like a fine solution to me. It's nice to be warned about surprisingly-slow tests but worse if that makes your tests flaky!
Running into an issue with pytest markers. Here's a rough outline of how my files are set up, all in the same directory:
pytest.ini
[pytest]
markers =
mymarker: My custom marker
conftest.py
@pytest.fixture(scope='module')
def my_fixture(request):
marker = request.node.get_closest_marker('mymarker')
if not marker:
raise RuntimeError('Missing marker, please add marker decorator to test class')
data = marker.args[0]
return data
myTests.py
@pytest.mark.mymarker("Hello")
class TestClass:
def test_my_test(self, my_fixture):
print(my_fixture)
When I run this, the "marker" variable in the fixture is always none (confirmed via debugger) and I always hit that error. Why can't this fixture see the custom marker?
Ah, apparently using the module scope for a mark on the class doesn't work. Switching the module scope to "class" fixed it
Should I just use normal functions instead of fixtures if my fixtures are callables invoked through the test functions
Pytest's docs have info about factories here: https://docs.pytest.org/en/6.2.x/fixture.html#factories-as-fixtures
I think the usefulness depends on your use case
Hi, i want to passed below test:
@pytest.mark.django_db
def test_login_post_view_valid_with_log():
client = Client()
url = reverse('login')
data = {
'username': 'test',
'password': 'test',
'captcha': '???',
}
response = client.post(url, data)
assert response.status_code == 302
assert len(User.objects.all()) == 1
form model for login:
class LoginForm(forms.Form):
username = forms.CharField(max_length=128)
password = forms.CharField(max_length=128, widget=forms.PasswordInput)
captcha = ReCaptchaField(widget=ReCaptchaV2Checkbox())
What should i write in 'captcha': '???', to login and passed the test by pytest module?
IMO if you can just use functions or context managers instead of fixtures, you probably should. If you know specifically why you want to use fixtures go for it, but until then they're probably just unnecessary complexity.
Yea they are unnecessary complexity, but I am worrying whether the errors will get harder to understand if I convert my fixtures into normal functions
I'd say: if you need something that last beyond the lifetime of a single test, or something that depends on such a thing, use a fixture. If the setup/teardown is just done once per test, use a function
fixtures do cut down on visual noise from with ... and other test setup code
when i worked on unittest apps i ended up writing a lot of utility wrappers around ExitStack for things like patches, setting temporary environment variables, setting up temporary database connections, etc. just to avoid having a ton of withs. and that was before parenthesized with syntax
There's no teardown / de-init for the fixtures I have, neither do I need any scoping features pytest offers
and functions will also save the type hinting code to support fixture usage
class A:
def a(self):
print("a")
def b(self):
print("b")
self.a()
def c(self):
print("c")
self.b()
def d(self):
print("d")
self.c()
self.b()
self.a()
Say I have this class. I would like to test it in order to know all methods that are called. So, if I call A().c(), I would like to get [call.c(), call.b(), call.a()]. Tried looking at Mock and patch but couldn't figure it out how to achieve that.
Not that easy β with mock/patch you would replace the entire class and see what gets called, but then you lose the logic inside it. In this case, you could do something like this:
!e
from types import MethodType
class A:
def a(self):
print("a")
def b(self):
print("b")
self.a()
def c(self):
print("c")
self.b()
def d(self):
print("d")
self.c()
self.b()
self.a()
class MethodWrapper:
def __init__(self, name, mock, method):
self.name = name
self.mock = mock
self.method = method
def __call__(self, *args, **kwargs):
self.mock.call_list.append(self.name)
return self.method(self.mock, *args, **kwargs)
class MockA:
def __init__(self, instance):
self.instance = instance
self.call_list = []
def __getattr__(self, attr):
val = getattr(self.instance, attr)
if isinstance(val, MethodType):
return MethodWrapper(attr, self, getattr(type(self.instance), attr))
return val
a = A()
mock_a = MockA(a)
mock_a.c()
print(mock_a.call_list)
@swift pewter :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | c
002 | b
003 | a
004 | ['c', 'b', 'a']
I.e., make a mock that logs calling of its attributes. It gets a bit messy though, as you can see
Wow looks nice thanks, will look into it and try to improve it (maybe with using Mock in order to get the arguments too)
It seems that calls to super methods not working well with this π¦
Yes, it's not very stable and only works with simple cases like this.
RIP
doesn't MagicMock already give you this for free?
!e ```python
from unittest.mock import MagicMock
m = MagicMock()
m.foo.bar()
m.foo.bar()
m.foo.bar.assert_called_once()
@pearl cliff :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | File "/usr/local/lib/python3.11/unittest/mock.py", line 902, in assert_called_once
004 | raise AssertionError(msg)
005 | AssertionError: Expected 'bar' to have been called once. Called 2 times.
006 | Calls: [call(), call()].
@graceful holly @swift pewter βοΈ
yes, but how would you combine that with the behaviour of the class?
I.e. if the real .bar() should call .bat(), how do you test that?
it depends on the test. if i'm testing each method individually, i'd set up a different set of mocks/patches for each call
e.g. when testing d, i'd set up patches for a, b, and c
but when testing c, i'd set up patches only for a and b
what you did is more general of course
Right, but what if you wanted to test the class A from above? You want to test all of it, and that the corresponding methods get called.
Perhaps this being strange and hard to do shows how you're "holding it wrong", that you shouldn't be testing that
i think a bit yeah, this is a weird way to test
Hi
you can set up the mocks in with blocks inside a single test method if you want
besides, what are you actually testing w/ these assertions?
either there's a problem where i/o is being intermixed with pure logic (not being pushed to the "edges") or there's a lack of intention in testing
mocking and asserting calls is like the absolute last resort imo
Hello guys
I got 2 jpg files that contain a graph (they are the same pixel to pixel)
I have to write a unit test using PYTEST where I can check whether or not the normal file is the same as the test version any idea???
Hi, i have a fixture that contains list with 4 files and a test that takes that list, extract the files into tuples, then works with it. For my test 4 files should be used but i somehow managed to get 16 usages, does anyone know why the test is called 4 times?
Fixture looks like this:
@pytest.fixture
def file_input():
files = [
"01.csv",
"02.csv.gz",
"03.csv.zip",
"04.npy"
]
files = [os.path.join(os.path.dirname(__file__), "data", file) for file in files]
return FileInput(files)
This is a more general question about testing - would you perform a system stress test in the QA environment if it had less HW capacity than your production/live environment? Or would you perform the stress test in your production/live environment?
yes
i'm not an expert in this area, but i think you can perform a stress test in the QA environment and still get useful information out of it. for example, if your QA and Prod environments both run on virtual machines in some cloud, and they're using the same machine types (but prod has more machines or has autoscaling enabled), then you can still get a sense of how each individual vm performs.
u a right btw. All you need usually to have sure your settings are at least confirmed switchable to handle more than one user at once.
surely, 100% HW stress testing can be done only in 100% matching hardware situation, but that's often not needed, and even running on weaker hardware, results yield 90% of usefulness
and that's kind of already enough
After all, no one prevents from extrapolating measured performance to higher hardware
the problem is that this extrapolation is not straightforward
it's easier with horizontal scaling but even then you might end up bottlenecked by your load balancer (unlikely) or the network connection of the cluster (possible)
sure. But as i mentioned often it is enough to check you don't have stupid dev settings handling 1 user only xD
with patch(storage._make_request, lambda: TestData.nodes):
not_parsed_items = storage._get_items()
in the mean time, how correclty to mock method xD
with patch.object(ProductionClass, 'method', return_value=None) as mock_method:
thing = ProductionClass()
thing.method(1, 2, 3)
nvm found
Hei, can someone help me with running django/python unit tests?
Hi, has anyone tried using Copilot to write unit-tests and was satisfied ?
If yes, can you share some suggestions on how-to?
Does anyone know if there's any packages or ways to detect what is clicking in a web browser? I mean get tag/xpath ? To afterwards find it via selenium or similar?
Like the codegen in Playwright or similar, like a form of listening.
hi! is it possible to use pytest for a test function and be able to assert a line without actually printing/returning anything?
Can you give a simple example? Testing a function requires calling that function, and if a function is called, then it has to either return something or raise an exception ( or crash the interpreter)
Maybe I misread your question so yeah, an example would help
test function does not have to return or print anything
but it is supposed to receive somehow data it wants to assert
in fact, pytest function returns do nothing xD
as well as any other unit tests in any language
Hey guys, do you know where i can get a library management system full course code with database included?
thank you so much! i figured out that setting the assert test_function() == None works for pytest to not catch it, and that if I only have things printed in the function its just returning None
again thank you so much for your help!
ohhh
thank you !!
also my question was really unclear lol but tysm for your help π«Ά
How do I unittest a library doing IPC with an application on Windows non-destructively? Like using docker for example but how?
How do I get started testing programs? Any courses to learn the basics of testing?
First this Unit testing book, then TDD (The first book is more theoretical to grasp the concepts, and second one is hand on practical)
also since i already second time answering your questions... here is roadmap of mine learning all this stuff and mentioning resources
https://github.com/darklab8/darklab_backend_roadmap/blob/master/swe_backend.drawio.svg
https://raw.githubusercontent.com/darklab8/darklab_backend_roadmap/master/swe_backend.drawio.svg
can someone explain to me what unit testing is?
read first chapters of to get thorough explanation
Shortly summarizing: Unit testing is essential code quality that should be present in code meant for productional usage.
Main advantages: Quicker development due to all previous code all the time automatically rechecked for being correctly working when new feature was added
Ability to refactor your code (improve from bad to good), since you can safely rename/replace code pieces with better written parts quickly and without fear to break your code
P.S. Deadly essential to python even in smallest non productional programs due to... Python catching errors/exceptions/typing problems only during runtime π
I find unit testing reduces development time by allowing me to test a large number of possible inputs without needing to run the application.
It also enables you to test how the API would look like and adjust for it
And to think through how it would be used, corner cases, etc.
I love that part, like this you get to actually test youre framework in many different scenarios, and then youre like "hmm maybe this isnt very practical" and then you change it or add some useful stuff
btw when using the builtin unittest library should I include the following at the end of the module?
if __name__ == '__main__':
unittest.main()
because I notice it anyways dosent get executed when doing py -m unittest, but tbh I just copied it from Corey Schafer's (old) tutorial on YT
This just makes it that you can just run the module directly to run the tests.
If you never do that, you may as well not have it.
then I shall remove it so I get a better coverage score lmao
def test_service_reg_return_correct_data(self):
m = mock.MagicMock()
m.data = { #dict
"user_name": "testuser26",
"password": "123456",
"email_address":"testuser26@example.com",
"dob": "2022-06-07 00:00:00",
"address": "Ahmedabad",
"uid": uuid.uuid4().hex
}
print("m", m)
with mock.patch("backened.routes.register.request", m):
response =user_register()
self.assertEqual(response, {'Message': 'New user Created'}) '''
AssertionError: ({'errors': {'_schema': ['Invalid input type.']}}, 422)
schema.py
class UserSchema(Schema):
print("Schema")
user_name = fields.String(required= True, validate=validate.Length(min=5))
password = fields.String(required = True)
# email_address = fields.String(required=True, error_messages={"required": " email_address is required. "})
email_address = fields.String()
dob = fields.DateTime()
address = fields.String()
uid = fields.UUID(error_messages={'null': 'Sorry, Id field cannot be null',
'invalid_uuid': 'Sorry, Id field must be a valid UUID'})
print("access")
@validates('dob')
def is_not_in_future(self, value):
"""'value' is the datetime parsed from time_created by marshmallow"""
now = datetime.datetime.now()
if value > now:
raise ValidationError("Can't create notes in the future!")
# if the function doesn't raise an error, the check is considered passed
class Meta:
# Fields to show when sending data
fields = ('id', 'user_name', 'password',
'email_address', 'dob', 'address', 'uid')
can anyone address this issue
Hello
Maybe because the entered dob is a string yet the schema defines it as DateTime
@wet topaz so how should I add this in test
My guess is that you have to update the function user_register to parse the input dob to a datetime object using something as follows dt_object = datetime.strptime(input_str, '%d/%m/%y %H:%M:%S') or update your test data to use said object instead of string
@wet topaz When I'm hit the API through postman I'm giving in this way "dob": "2022-06-07T00:00:00" and it is executing fine.
Did you try using the string "2022-06-07T00:00:00" instead of "2022-06-07 00:00:00"?
yes
@wet topaz https://stackoverflow.com/questions/74671699/assertionerror-errors-schema-invalid-input-type-422-mes
here is the implementation
you've got me on this one, anyone else?
haha... no worries
if you change dob and/or uid to a string in the schema, do you still get the same error?
Iβve done by changing the schema to string instead of date time
But I will try for that too
Hey guys, is there a way I can set up PyCharm's pytest to accept args?
I don't know pycharm per se, but setting the addopts entry in a pytest.ini should work
def getUniqueColors(img):
uniqueColors = []
for row in img:
for color in row:
if color not in uniqueColors:
uniqueColors.append(color)
return uniqueColors
#TESTING CASES#
def testPurpleColor():
assert getuniqueColors(purple) == uniqueColors
hey im not god at unit testing, how can i test this?
In this I've mocked connection but how to mock insert query?
Perhaps you could use a sqlite database just for test data
here is an example https://blog.devgenius.io/creating-a-mock-database-for-unittesting-in-python-is-easier-than-you-think-c458e747224b
Use the power of pandas and sqlite to set up a mock database table in a couple of minutes.
It is better solution than mocking.
But still not best. Better setting up running tests in Docker compose with appropriate dB like Postgresql
https://github.com/darklab8/darklab_article_docker_python/tree/master/example_frm_fastapi
With this library a container spins up automatically when running unit tests:
https://github.com/testcontainers/testcontainers-python
apparently it can spin up many different containers
Hehe. solution from java world
rather good choice i guess
for people not too much intimate with docker
I tested it once and it worked quite well, heard about it at dockercon 2022
i think it is not flexible enough option. rather limited amount of available docker images, no redis for example
good point
solution to utilize https://taskfile.dev/usage/
for easy manipulation of docker-compose written makefile in yaml is more powerful at this point to run test/setting up quickly dev env shell
(docker-compose run can be reused as internal sub task there, making very simple commands in the end)
Hey, there was some clever way to prepare test data, for different test. How to do it in pytest?
I just want to load same image every test, and then just run 4 of them on same data.
Perhaps using a fixture? https://codedec.com/tutorials/pytest-fixture-and-setup-teardown-methods/
that will do, thanks
with setup_module setup_class or setup_method test will share context right?
Hey @worn magnet!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
Hey @worn magnet!
You either uploaded a .txt file or entered a message that was too long. Please use our paste bin instead.
https://paste.pythondiscord.com/atasuculam Any improvements I could make to this it is in a working state just wondering if I could make it more efficient or more user friendly. Sorry if this is the wrong channel
few or more, try #βο½how-to-get-help
Got problem with pytest, don't know what flag use to show full error π
Oh ok thanks
is this normal for tox? I'd expect it to use a 310 binary
$ readlink .tox/python3.10/bin/python
/usr/bin/python3.8
./.tox/python3.10/bin/python --version
Python 3.8.10
my envlist is py38,python3.10, maybe it thinks 3.8.10 is 3.10?
@wet topaz I've tried that but I need to mock query
you can take a look in this link https://stackoverflow.com/questions/74748112/python-mocking-how-to-mock-sqlalchemy-query
:incoming_envelope: :ok_hand: applied mute to @proper wind until <t:1670627031:f> (10 minutes) (reason: duplicates rule: sent 4 duplicated messages in 10s).
The <@&831776746206265384> have been alerted for review.
Why do you need to mock a query if you have a test database?
@wet topaz Iβm planning to mock all external dependencies adv: coverage , less code plus I want to know how(biggest reason)
!e
code
!eval [python_version] <code, ...>
Can also use: e
Run Python code and get the results.
This command supports multiple lines of code, including code wrapped inside a formatted code block. Code can be re-evaluated by editing the original message within 10 seconds and clicking the reaction that subsequently appears.
If multiple codeblocks are in a message, all of them will be joined and evaluated, ignoring the text outside of them.
By default your code is run on Python's 3.11 beta release, to assist with testing. If you run into issues related to this Python version, you can request the bot to use Python 3.10 by specifying the python_version arg and setting it to 3.10.
We've done our best to make this sandboxed, but do let us know if you manage to find an issue with it!
hey can anyone help me with fixing my code
import unittest
class MockArmor:
def init(self):
self.durability = 10
def protect(self):
return 5
class MockWeapon:
def init(self):
self.durability = 10
def damage(self, value):
return value
def hurt(self):
return 1
class TestChar(unittest.TestCase):
def setUp(self):
weapon = MockWeapon()
armor = MockArmor()
self.char = Character("Jesus", 10, armor, weapon)
def test_take_hit(self):
dmg = self.char.armor.protect()
self.assertEqual(dmg,5)
def test_hit(self):
dmg = self.char.hit()
self.assertEqual(dmg, 1)
What's wrong with it?
Did you import it?
no
Idk. Where did you make the character class?
can you tell me how can i make a new one
like what should i import first to make a new one
i just wanted to make mock armour class
class MockWeapon:
def init(self):
self.durability = 10
def damage(self, value):
return value
def hurt(self):
return 1
like this is the weapon class
and i want to make armour class similarliy
I thought you already did
no
Mock armor is the first one
yes but its showing the error
Show error
wait
can you help me in making a new mock armour just the protect() class
and testchar class where my character class is not defoned
Does anyone knows here how to test VHDL /FPGA using python ?
that would be an interesting topic I assume you will need to read data from serial port to python from the fpga ?
Hey, im pretty sure this is the right channel, but i need help with my 3d renderer
im having a problem with my rendering method where i get a little bit of good model and then just a funny looking pile of junk right next to it
Hey @deft oracle!
It looks like you tried to attach file type(s) that we do not allow (.zip). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a, .csv, .json.
Feel free to ask in #community-meta if you think this is a mistake.
Sorry for advertising a help channel but I would like some feedback on an error I'm getting while using MagicMock here -> https://discord.com/channels/267624335836053506/1052111566553751582
I've got a question to ppl with some experience or ideas of fast api and testing... Does it make sense to have endpoints tests that would validate response structure? Considering that response structure is dictate and validated by response schema with pydantic?
yes and no. No, since technically nothing is added to pydantic model used to define input of the endpoint
but still Yes, because additional multiple functionality is present through this defined schema, with those field factories stuff
And frameworks other stuff participates like middlewares in addition
So at least one test should be present for endpoint to check sanity of it. Essentially checking response structure is not really needed though... since what is the point to test already stable library?
But since python typing allows to configure incorrect response models to those endpoint, test checking response structure should be present in order to validate response structure at runtime! (Since your endpoint can be actually having missleading wrong outdated response model)
U need very simple test for it though, just enough to deserialize back to some pydantic model
Situation with this testing will be better if project will be covered in typing like with mypy, then major part of it will be just done through it
I was thinking to add pyright eventually yeah
Correct
I Can show you the system structure if you like
Got the code
is unit testing the same as writing check-expect in racket?
Does anyone here have knowledge of python module tkinter
Yup why not
Given the following Python code which exists in file "app.models.datasource":
Datasource = Union[
Athena,
BigQuery,
PostgreSQL,
MySQL,
Redshift,
Snowflake,
Trino,
]
class DatasourceInput(BaseModel):
__root__: Annotated[Datasource, Field(discriminator="engine")]
How can I mock DatasourceInput so that when it is referenced the following implementation is used instead:
Datasource = Union[
Athena,
BigQuery,
PostgreSQL,
MySQL,
Redshift,
Snowflake,
Trino,
SQLite, # <-- Difference is here
]
class DatasourceInput(BaseModel):
__root__: Annotated[Datasource, Field(discriminator="engine")]
I have the following in conftest.py but the original is still being used.
Datasource = Union[
Athena,
BigQuery,
PostgreSQL,
MySQL,
Redshift,
Snowflake,
Trino,
SQLite, # <-- Difference is here
]
class DatasourceInput(BaseModel):
__root__: Annotated[Datasource, Field(discriminator="engine")]
@pytest.fixture(autouse=True)
def add_sqlite():
mock.patch("app.models.datasource.DatasourceInput", DatasourceInput)
Does anything stick out as wrong to anyone? Appreciate the help.
in selenium, when do we use ActionChains?
Noob question about pytest:
which functions of a file will be run by pytest, is it all functions that do not have arguments?
Thanks!
All functions starting with test_, by default.
plus the only ones which are in files starting with test_* name too
pytest.ini overrides for tests.py files are necessary if used
Hey guys, I'm really confused here
I stored tests intended to be run with pytest in a directory named tests
but this is all part of a PyPI package
so the tests dir is in the top level, where src is also located
src contains the source distribution for the package, which looks like src/package/...
so in order to import package modules from the test files I need to add some seriously weird relative import statements
and if that was not enough, I also have to create multiple __init__.py files everywhere (even in the root dir, which should be only dedicated to the package files) so that I can create a "bridge" to import src files
does anyone know an easier and cleaner way to do this?
mainly because all those __init__.py files don't quite feel right
I don't think you need to include tests as part of your release?
@river pilot Hello, I'm using coverage.py with pytest, I wonder if there's a way to exclude function calls in certain places from coverage:
def function():
pass
def run_pytest():
function() # pragma: no cover
if __name__ == "__main__":
run_pytest()
This still reports coverage of 100%
I need to generate some test data using a function that is also being tested in another module π
tox4 is nice
I believe the official documentation would not state this
tests/ is a placeholder for test files. Leave it empty for now.
if they were not meant to be included as part of the package
No, the pyproject.toml, README, etc. is also not part of the package. It should be part of the repository, but not (usually) of the package. Your users shouldn't need to execute/have your tests.
That's why, in the example, tests is not within example_package_YOUR_USERNAME_HERE or even just within src/.
(I'm assuming you go that from here: https://packaging.python.org/en/latest/tutorials/packaging-projects/?highlight=leave it empty#creating-a-test-directory )
Yes, that's right
I should remake my question
Given that tests directory, is there any cleaner way to execute the tests without all those relative imports __init.py__ files?
Installing your package in a virtual environment and then importing it as any end-user would.
but there are test files that should not be accessible to the end user, as you said before, since they are outside the package
Right, but you are talking about importing your package inside tests, right?
A better question would be: what kind of tests should that top level tests dir contain, since it is hard to import the source code located in src and the contents of the tests should not be distributed?
Yes, but locally
with relative imports
I reject your premise. It's not hard to import, just do pip install -e . in your main folder and then do
import mypackage
, etc. in the tests
No need for relative imports
Sorry, I didn't understand the question... which function do you want to exclude? You can put a "no cover" comment on the def run_pytest line if you want.
Function itself is already excluded from tests since it'd be in tests directory π€
I am using another function to generate test data, I also test the same function because it's used in actual code, so I'd want to exclude a specific call to it
Would that be possible?
what does "exclude a specific call to it" mean? You want to measure the code, but not when it's being called from a particular place?
Yep
coverage.py doesn't have a way to do that.
Ok, I see, I'd have to populate my test data in a different way then
Thanks for your help
why not just let the test-populating calls count as testing the function?
Because they just call it and mess up my coverage, it's tested separately
e.g. I don't test if objects are created properly because I only use their ids as foreign keys in that test
Hey! I'm currently doing a Py take home test for a job I applied to(Idk any Python). I made that clear in my interview that I've only worked on JavaScript. Any advice? Am I doomed? lol
I knew very little of Python too for my first job interview. It did not stop me from shining enough to get hired
Probably because.. I was super lucky to get practical task with creating Flask blog within 5 days from zero, and not everyone may be is enthusiastic enough to do it.
Two like souls π
Any advice? I'm pretty Junior. I've worked for 2 years but weirdly never needed much JS..let alone having to a Python test(first coding test for a job too).
Also this is not related to art of unit/integration/end to end and etc auto tests, it is #career-advice as first, and #web-development as second
Very quickly more familiar with this book π
Oh sorry, the test is asking me to refactor code for easier unit testing.
Oh
That is very interesting task to give to interviewed
I should add somewhere note to ask interviewed people too about it
The title is "Senior Python Developer Test"..I made it clear I'm entry level lol.
They wish to find future seniors among juniors and getting benefits of (in future) seniors for cheaper price. The usual scenario
Tbh, this is totally topic from middle rank of software development. I can obviously recommend materials to learn it... But it will involve too many books, which u could not possibly learn within the time of already recieved task
At best...
I can try showing example of small unfinished code example regarding it
Up to u of u will be able to scrap anything out of it
This is #software-architecture question first btw then, and well #unit-testing too of course, but will be easier to get answers in software design
Lets say i got some datastructure
tree_instance = ItemsTreeDS
which is declared in module
But I would like to share instance that is loaded in new_instance test, and pass is to other tests, to do some checking on this single load case.
I could do load manually, and then pass it to each test, but i don't want it, unless its only solution
@pytest.mark.dependency()
def test_2_save_check():
tree_instance.save(test_data_folder)
@pytest.mark.dependency(depends=['test_2_save_check'])
def test_2_new_instance():
tree_instance = ItemsTreeDS(load_path=test_data_folder)
# assert not tree_instance._loaded, "Should not be loaded"
# tree_instance.load(test_data_folder)
assert tree_instance._loaded, "Should load"
@pytest.mark.dependency(depends=['test_2_new_instance'])
def test_2_load_check():
assert not tree_instance._loaded, "Should not be loaded"
tree_instance.load(test_data_folder)
assert tree_instance._loaded, "Should load"
@pytest.mark.dependency(depends=['test_2_load_check'])
def test_2_multi_load_check():
tree_instance = ItemsTreeDS()
assert not tree_instance._loaded, "Should not be loaded"
tree_instance.load(test_data_folder)
tree_instance.load(test_data_folder)
tree_instance.load(test_data_folder)
assert tree_instance._loaded, "Should load"
tree_instance.do_tree_check()
It's generally bad practice for one test to depend on another. Each test should get its own resources.
i actually removed dependencies, but sharing same object is fine? one test checks one variable, other test checks something else
No, don't share objects between test cases. Each one should get its own object. The tests should be isolated from each other.
what do you suggest for big data structure?
many loops to process all stuff and be ready
isolation in my case seems kinda wrong π€
Can you work with smaller test data so it has less to process?
The concern with re-using the same object across tests is that one test could introduce a mutation that causes some other test down the line to break. And it just becomes harder to debug then.
Maybe I could, but thats additional work to make.
Or on the flip side, one test could be causing another test to pass, but if that test were to run in isolation it would have failed due to some bug in the code.
Like a "x only works if y is done first, but we want x to work by itself" situation
ah ye, its not super big data, just 13k items to process.
good point, thats why I actually test loading separately :D, and on other hands I would just test queries, so yea. Its processed only once, and then nothing happens :d
13k items to process sounds excessive for unit tests. If you wanted to do a stress test then that'd be a different story, but even then, those generally don't run as often during development so it's more acceptable for them to take a longer time.
thats just all parts from game, so I try to find best parts* using minimal resources, limiting data would make tests also harder to predict π
i can agree to that, but will keep my for now, anyway thanks for help, learned something new
You could have a separate test that processes everything, and run that only when you're about to do a release or something. And for development you just run a subset of the data as a sort of "smoke test".
If you do that, then I don't think it makes sense to have unit tests processing all data. Maybe for an e2e test that would be more sensible
Would be curious to hear other people's thoughts about that as well
without whole data, some weapons could be useless, how would you debug that?
I was pretty sure my algo was fine. But then I some other query and realised one weapon has different dependencies in json π
Right, your tests are only as good as your test cases. If you don't think of a certain case, then your tests will miss that. That's why I do see value in processing all files - I just don't think it's appropriate to do that at the unit test level, and to have that as part of the test suite that runs very frequently. Developer time is valuable and we wouldn't want them sitting around waiting e.g. 15 minutes for tests to pass every time they make a change.
and that is the reason I share object ;d
so we got same goal, but different path. Also my data set is smaller, I added one number, its 1400 items~
traders: 1851
slots: 2056
items: 1568
so my tests run in 6s so I think thats long and thats why I don't want to completly separate everything
Well my point is that you should have tests with less data that can run reasonably quickly during development, and a more comprehensive test suite that runs in your pipelines.
6 seconds is not long at all.
If I could easily split data probably I would π
Hey guys, can someone tell me what would be a recommended way to create multiple model objects which are saved to db for flask app testing? Those Model objects would be used in multiple tests, so ideally they should be defined only once. Currenly for each model object I use a separate fixture, but now I ended up having multiple fixtures for each used model, making a lot of repetition.
So im totally new with writing tests. It doesnt seem that hard but at what point is is good to start writing them? Do you make tests upon writing a new feature or do you write tests when the first version of the core program is done? How complicated do they have to be?
Read the book
Unit testing Vladimir Khorikov
TDD by Kent Beck
It will give understanding
Tests are always written at the same time as new feature or bug fixes are added
The only difference is, people write some feature part then tests, or tests first and then another feature part.
Book TDD Kent Beck will give you feeling of a step size to make between tests
Aight mate, thanks!
You can just define a fixture in common conftest.py module, but fixture itself has to be function scoped (that's the default) since in 99% of cases you want to clean db after each test
Hello how to get started in testing? Which one should i study unittest or pytest?
Same problem
Really which one should we study?
I figured both of them are well and could be combined!
but is that good way or we must be use one of those?
I think pytest is a better framework so I would start there but it may be useful to study unittest too because you may be on a project where unittest is preferred.
Pytest is pretty much an industry standard at this point. I have only seen unittest in cpython codebase
But yeah, starting with stdlib is always the right choice, I think. Even with urllib
For well used protocols/use-cases it tends to be a good idea to go with faster moving 3rd party libraries,
Aka stuff like httpx, django/flask, pytest (shameless plug π), rich, click, packaging, etc
Pytest is awesome, mainly because of modular fixtures, which are very useful, I didn't see any other testing framework with similar feature, maybe except rstest π€
As i have understood patch replaces a value of function with something without the actual calling . So what could be the possible use of calling patch with one argument(just the path and no replacement value).
π
It defaults to replacing it with a mock object
If new is omitted, then the target is replaced with an AsyncMock if the patched object is an async function or a MagicMock otherwise.
(new is the name of the second argument)
Hi all!
I just wanted to share my new open source library, FunUnit, with the unit testing channel. FunUnit is a functional, declarative unit testing library for testing pure functions in Python. It removes boilerplate testing code, allows you to describe tests in a declarative manner, and is great for testing pure functions.
I'd love to hear your thoughts and feedback on FunUnit. You can find the code and documentation on GitHub at github.com/johnmpost/fununit. I hope you'll give it a try and let me know what you think!
How can I set an internal attribute within a spec_set mock class?
from unittest.mock import Mock
class MyMockString(Mock):
def __init__(self, **kw):
super().__init__(spec_set=str, **kw)
self._foo = 1 # AttributeError
Please ping on reply
can some one check my test here someone professor ask me in fiverr to make him a python hacking test to make he gave me topic to do it off i dont know if the program is to easy or not can some one check it pleas and say what i need to change its realy importent to read the ruls i worte on the test in the readme.md you cant do the test without them https://github.com/IdanHajbeko/try_to_hack
π
Hi all,
I would like to know the best way to write an unit test for my ftp code that connect to real ftp server and that can't be used for testing.
Thanks in advance
the common solution is to have something like the ftp client be replaceable by a mock and/or having a fake server to test against (any test that runs against a network server is at least a integration or unittest
anothre option is to have the logic separated out so that you can test the detail bits of a workflow without needing to go to the network
maybe run the ftp server as a container and connect to that in your unit tests
anyone know how I can find more info on what happened here
[3.8 to 3.11] x [win, macos, ubuntu] all passes, except for 3.8 win and macos
where I just get this from pytest -v after all tests pass
============================= 52 passed in 0.79s ==============================
Error: Process completed with exit code 1.
and for macos
============================== 52 passed in 0.74s ==============================
/Users/runner/work/_temp/3218124e-6796-46b3-a264-71a085611569.sh: line 1: 2314 Abort trap: 6 poetry run pytest -v
Error: Process completed with exit code 134.
I suggest you add code snippets in the documentation
hi! what's the best way to write a unit test for a guizero based program?
If it doesn't have recommendations itself, you may be in a terrible position
I'm struggling to mock a @cached_property on my class in a unit test.
# The code I'm trying to test
from .other_class import OtherClass
class ClassName:
@cached_property
def cached_property_method_name(self):
return OtherClass.class_method_being_called()
I tried using the following method:
@pytest.fixture(autouse=True)
@patch('path.to.module.ClassName.cached_property_method_name', new_callable=PropertyMock)
def patch_it_up(mocked_method):
mocked_method.return_value = MagicMock()
In the code I used traceback to print the stack and it is clear that the patch is not working properly.
I also tried to patch the class and class method being called within the cached property and that also didn't work.
@pytest.fixture(autouse=True)
@patch('path.to.module.OtherClass')
def patch_it_up(other_class):
other_class.class_method_being_called.return_value = "my value"
I've tried to go from @cached_property to @propery and immediately the patch works.
does anyone see anything that I'm doing wrong or know the right way to do this in Python 3? I couldn't find anything with a Google search related to this.
UPDATE 1: I dug a little deeper and I'm guessing the path forward would require actually patching cached_property, is that right or totally the wrong path?
UPDATE 2: Upon further reflection I think it may be that I'm not patching the function soon enough and I need to find a way to patch it before and/or after it's passed into functools.cached_property
Thanks!
the example you showed always is kind of a "integration test" - it would be hlepfull to elaborate a bit more on the actual use-ase to be able to suggest a viable strategy
Essentially I want to stub out the class that I depend on to isolate it from the rest of the unit tests. For example, I want to assert that the initialization method is called with the right arguments. Then I want to ensure the returned instance is used appropriately in the rest of the class.
It sounds very painful to test that way with patches, do things have to be structured that way? (for example, why not call the function of the cached property with appropriate mocks set up)
Let me send you PR so you have even more context. I could totally be overlooking something super simple here, https://github.com/celery/kombu/pull/1640
I think I tried what you're describing, and it didn't work -- although I'm not sure I fully understand what you're suggesting. I'll update the PR to what I had originally, before going down this rabbit hole π
I'm concerned that I've been mocking the class method incorrectly this entire time.
@ember maple This is what I did originally: https://github.com/celery/kombu/pull/1640/files#diff-b0bedc49492dc4617d038b372a79b00d338ff39263405569256d4fe1b229d61dR206-R218
@ember maple π€¦ββοΈ I just realized this entire time I was working as if this is a class method, but it is an instance method!
Update: I still can't get this working lol. Any help is appreciated.
You know what I think would help me the most is validating that the way I mocked the class method is actually right.
Personally I like to avoid mocking when possible, in particular when it needs patching
Im currently unable to dig into the code you linked
@ember maple FYI: I was able to get this working very simply by not mixing decorators (i.e. @patch and @pytest.fixture). That was fundamentally my issue. As soon as I switched to only using a single type of decorator in my tests, it worked. See the PR if you're curious.
Hi, I have a question regarding unit testing a function that generally calls other functions, for example: python def sync_db_and_bucket(): # Pull data from database db_training_data_df, db_evaluation_data_df = get_data_from_db() # Validate and clean the data training_data_df = validator.prepare_data(db_training_data_df) evaluation_data_df = validator.prepare_data(db_evaluation_data_df) # Convert to csv and store to the bucket bucket_name = 'example_bucket_v2-aiproject-dit825' store_data_to_bucket(training_data_df, bucket_name, 'training_data/media_bias_dataset_cleaned.csv') store_data_to_bucket(evaluation_data_df, bucket_name, 'evaluation_data/evaluation_data.csv') I have this function. To unit test this, my first thought is to make sure that the correct functions etc are called. Im then wondering, would this even be a good unit test, ie should unit tests really care about the implementation details?
Hello. I am trying pytest and got some problems about PATH. Not sure if I am doing something very wrong or just I don't understand how the pathing works. Can anyone take a look and help?
My problem: I can only run the test with cd tests/; pytest. Run the test pytest at top level will cause FileNotFound error.
Is that a design problem on where I put the test case (which is not the correct way to use pytest) or something else is wrong?
My repo structure:
/ (top level, my working directory)
pyproject.toml
--src/
----my_module/
--------my_module_helper.py
--tests/
----test_module.py (the testing code)
----test_cases/
-------some_text_files.txt
I don't really want to install my_module in my own machine now as I am still working on it.
My test_module.py needs to import from my_module in order to test my codes. And I have to include the src as my Python path. I do that in pyproject.toml.
[tool.pytest.ini_options]
pythonpath = ["src"]
So my test module works.
import pytest
from my_module.my_module_helper import *
However, the problem occurs when I try to load test_cases/some_text_files.txt
I try to read the txt file from test_module.py
@pytest.fixture
def some_cases():
return read_from_file("test_cases/some_text_files.txt")
def read_from_file(path):
with open(path) as file:
for line in file:
# ...
Then I run pytest or python3 -m pytest from top-level directory. I get FileNotFound error.
FileNotFoundError: [Errno 2] No such file or directory:
Then I added conftest.py in tests/ and put the load text code there. Still get FileNotFoundError.
The testing can only run if I cd tests/; pytest.
Are there anything wrong with my structure or settings?
Would it work if you add an absolute path to the file?
In pythonpath in pyproject.toml? Or change the path in return read_from_file("test_cases/some_text_files.txt")?
Has anyone here ever done integration testing with an API? I'm curious how that would work. Obviously you can unit test an API by mocking out the request, and that works great until the API changes π some places have sandboxes, but those sandboxes often have rate limits, etc.
Is there actually a solution here? I hear people talking about integration testing with an API, but I've never actually seen anyone do it.
I changed it to absolute path. return read_from_file("/the/full/dir/test_cases/some_text_files.txt") It works. But I don't think it is a good solution
I suppose you could run the api server in a container and run your unit tests against that
You can test whether the functions are called with the expected data, or assuming this is storing data to s3, you can run the s3 service in a container, call this function and test the contents of the bucket hosted in that container
Whats the best way to handle failing tests on master? It is good practice to make an issue for it, and then disable the test? Is there a way of marking a test as failing in pytest? Or is this a dumb question and it doesn't matter?
Actually, just found out about mark xfail as per this part of the docs:
https://docs.pytest.org/en/7.1.x/how-to/skipping.html
Do u have multiple Devs using branching workflow? (Pull requests)
Or u have single Dev always developing in master
This is definitely wrong and worst choice out of all existing. Don't do it
Yes, multiple devs working on the project using PRs. For some reason a test started failing on master despite no change in the source code (I think its a problem with a dependency). I've reported it in an issue, but thought it would be good to disable the test for now until someone can give it a proper look.
What's wrong with marking it as .xfail?
And what are the other choices out there?
You have CI?
That runs in PR
Problem is solved by enabling setting that allows merging only when branch is up to date to master + tests of CI ran
U have master broken, because outdated branches introduced changes conflicting with latest
Enable forbidding merging outdated branches
I have CI that only runs on PRs. The last commit was Oct 2022, where the CI ran file. I changed a part of the README today, and on the PR the tests failed. So there is no way a merge caused the failing tests, I think its a problem with a dependency (/how we're using it).
I don't know if you understand my question. My question is generally how to handle tests that start failing (not due to a merge). From the reading I've done I think .xfail is the right answer
I don't see what's wrong with using .xfail
Thanks for your help though π . Let me know if you have any more thoughts
bit slow to reply, but I was more thinking like, "How do I test that my code works with the recent Paypal API changes", so I can't run the Paypal API server for obvious reasons.
I think the answer is to probably spam staging for APIs that have staging π
Sorry to bring up old post. But anyone can give me ideas?
tests are there to ensure your code is correct. They are exactly to prevent situations like this
- preventing errors appearing from refactoring
- preventing errors appearing from third party libs changing their code
the correct way is to fix code, why they became failing
if u disable test... it is same as
try:
some_code()
except Exception:
pass
you are silencing errors, which is the worst thing to do.
- your obligation is to fix code why it is not working
- in the worst still acceptable case, you are obligated to leave the code with failing tests as it is. leaving indicator to future people dealing with it, that application is not working
but never silencing tests.
I'm working on configuring the CI/CD pipeline, so wanting to debug that was my motivation for disabling the test. But I think you're right, disabling the test in master is the wrong thing to do. Thanks for the advice π
@maiden pawn The maintainer of the package also commented the same thing while I was asleep π . Cheers for the insight
How can I test all the docstring examples in a package?
I tried py -m doctest module.py but ofc it gives me: ImportError: attempted relative import with no known parent package, which ig is normal when running a module that has relative package imports.
This is one of the tests im trying to run:
https://github.com/shner-elmo/FlashText2.0/blob/master/flashtext2/keyword_processor.py#L43-L49
flashtext2/keyword_processor.py lines 43 to 49
>>> from flashtext2 import KeywordProcessor
>>> kp = KeywordProcessor()
>>> kp.add_keywords_from_dict({'py': 'Python', 'go': 'Golang', 'hello': 'Hey'})
>>> my_str = 'Hello, I love learning Py, aka: Python, and I plan to learn about Go as well. ' \
'(I can ignore substrings as well, for ex: goal)'
>>> list(kp.extract_keywords_iter(my_str))
[('Hey', 0, 5), ('Python', 23, 25), ('Golang', 66, 68)]```
Pytest discovers auto docstrings too
Is there a way to not get this error when the output is basically the same? (when testing docstring examples with pytest)
Expected:
{'java_2e': 'java',
'java programing': 'java',
'product management': 'product management',
'product management techniques': 'product management',
'java': 'java',
'python': 'python',
'c++': 'c++'}
Got:
{'java_2e': 'java', 'java programing': 'java', 'product management': 'product management', 'product management techniques': 'product management', 'java': 'java', 'python': 'python', 'c++': 'c++'}
https://docs.python.org/3/library/doctest.html#doctest.NORMALIZE_WHITESPACE
This looks useful to your case
unfortunately you cant run doctest on modules that are inside a package, unlike pytest
https://docs.pytest.org/en/7.1.x/how-to/doctest.html#using-doctest-options
There is code example how to enable doctest whitespace normalizer in pytest
(all your answers are once again found in official docs)
thanks bruh
why didn't you use mock?
What do we generally do in unit testing?
Testing oure code)))
This book is dedicated to explain at level what it does and what ways to have it done exist
I think quite friendly and good explaining. It explains what kind of testing types exist and why we need it
I prefer editing the text file to modify a string and tuple in my case
!rule 5 (unless you prove it otherwise)
5. Do not provide or request help on projects that may break laws, breach terms of services, or are malicious or inappropriate.
You wΠ°nt to do this in tests?
teacher explained to me that tests should not open files, files must bee mocked
I never learn anything about testing, could you tell me more about why files should not be opened and should be mocked instead?
I am just writing (unit) test for my stuff
So I have text like these
ABCDE YYWWW
BAFGH YYWWW
...
I use these simple cases to verify my logic. I internally transfer them as a list with many tuples + something
This depends on the situation. It is usually a bad idea to open real files for tests. But sometimes you need to test against preprepared data, and sometimes the best way to do that is to store the data in a file.
I suppose these files are easier to see/maintain then lists of tuples of strings
Because, enyone cann do some changes in youre file, and ruine test
Yeah. If your inputs are 0, 1, -1, 100, then that's easily stored in your script. But if you need a huge complicated input to trigger some weird edge case, then that might be better off in a file.
No. I define these tests and I have control over them
@patch('builtins.open', mock_open(read_data="data"))
def test_as_expected_file_processor():
assert file_processor('data') == ["data"]
@patch('builtins.open', side_effect=FileNotFoundError)
def test_fail_raises_file_processor(mock_file):
with pytest.raises(ValidationError) as exc_info:
file_processor(mock_file)
assert str(exc_info.value) == 'This file not found, try another one!'
Im new in programing, and maybe I'm wrong
π
but looks logical
In some situations they should be. In most situations they should be not mocked.
It really depends on a case
I have tried both of them. Actually thatβs true though pytest is a wonderful however itβs seems like django tests are based on unittest. Iβm not sure nevertheless I wanna learn more about it as soon as possible.
Django works perfectly with pytest
Just install pytest-django for correct integration
So that you telling me to stop using unittest?
It's seems everywhere pytest is better choice!
Yes. unittest makes sense only for scripts without installed libraries.
If u work with with Django, makes sense to setup pytest too. One more, one less dep, no difference already
Is it any references for diving to pytest?
Official docs are pretty fine
Cool, thanks buddy
I'm new in test π
Pytest isnβt object base like unittest?
I mean using class to write tests.
Docs of testing framework are completely insufficient to learn how to test code. U need to learn code architecture for this.
Consider reading:
Grocking Algorithms
Object oriented Python ivy kald
Unit testing best principles by Khorikov
TDD by Kent Beck
Code Complete by McConnel
Head first Design Patterns
Clean architecture Robert Martin
Order is provided best for reading
Wow thatβs awesome. Thanks a lot
https://stackoverflow.com/questions/50016862/grouping-tests-in-pytest-classes-vs-plain-functions
Using classes for pytest is optional feature for additional grouping capabilities
Cool π I appreciate you
just linked url right below your message 
u will get something like
class TestContructorIsStreamValid:
"""A class suite to test ifstream smth"""
@pytest.fixture
def d(self):
"""This fixture will only be available within the scope of TestGroup"""
istream *is = new ifstream("data");
Doc d(*is);
return d
def test_assert_empty_is_false(self, d):
assert d.empty() is False
def test_assert_size_correctness(self, d):
assert d.size() == 3
Technically nothing prevents you from writing
@pytest.fixture
def d(self):
"""This fixture will only be available within the scope of TestGroup"""
istream *is = new ifstream("data");
Doc d(*is);
return d
def test_assert_empty_is_false(self, d):
assert d.empty() is False
def test_assert_size_correctness(self, d):
assert d.size() == 3
tests in pytest are autodiscovered based on test_* name
dunno. probably yes. Not very often used feature. Classes in python are used just as rarely used feature to limit scope of defined fixtures and for additional test grouping for readability
@pytest.fixture
def d(self):
"""This fixture will only be available within the scope of TestGroup"""
istream *is = new ifstream("data");
Doc d(*is);
return d
makes reusable feature automatically supplied with its value to test if the test has function name in function arguments
see that def test_assert_empty_is_false(self, d): has invoked d
it depends on clean code readability. if it makes sense to group them and limit scope of fixture, then do. if not, then not.
it depends on your intention you wish to tell to other developers
usually people very often make a lot of files with tests to group tests otherwise
i think using classes is more convinient than creating too many files for tests
also limiting scope of fixtures to class is convinient in my opinion
than less stuff has scope, then better
what is reflection?
sorry not too familiar with low level languages yet
will their name be seen as tests that failed? yes.
funny enough, recently i tried to hook testing framework to C++ project in some open source project, but gave up. I am too much not familiar with C++
may be u are interested to setup for some open source community this stuff π
they wish to have testing xD
we tried to choose Catch2 + Typemock (the code has a lot of legacy, and this mocking framework is rich in functionality to replace hardcoded stuff)
but kind of very difficult to setup
setup anything π We were unable to configure anything anyway.
well, sounds like a matter of correct code architecture to insert mocks for dependencies in correct places + a bit mattering to know how to use your framework configuration in order to override some framework global deps too
well, what are you using, Flask, Django, FastAPI
okay
you are creating some kind of script then?
well, then it is even more simple. Overriding your own code deps... is always simpler... as long as you know code architecture stuff
especially overriding deps is simple in python... because it is dynamic language.
anything can be overriden at runtime (including all consts and imported libraries xD)
by default pytest is not showing output of passed succesfully tests. they do not matter for this 
for succesfully passed tests, pytest just writes one dot .
so multiple tests are seen as passed like
...............................................
pytest automatically shows details only for failed tests
with tracelog
and with detail which test names failed
we group tests in pytest purely for readability of code, and for selecting sub group of tests separately during debugging or test writing
we can always see all tests explicitely during test run... but no reason.
vscode extension pytest, allows comfortably running specific tests from GUI π
also pytest -s -k test_part_of_name, selects all tests for running that contain test_part_of_name in their name (test_part_of_name*)
very good thing to have, because it also allows using Vscode visual debugger
with step by step analyze of a test
otherwise python is always having CLI debugger PDB.. not not very convinient thing to use always
(inserted anywhere breakpoint() for its running)
Install pdbpp for more convenience
There's also the jupyter alternative for that tho
Pdbpp
Please, try it
Python Test Explorer For Visual Studio Code (enabled in pytest mode)
using jupyter is evil and worst thing to do π don't
You'll love it. At least I did
by default test_ files aren't discovered. pytest.ini config file adjustment is required.
pytest.ini
[pytest]
python_files = tests.py test_*.py *_tests.py
or may be tests.py aren't discovered
i don't remember π
put pytest.ini file in root of your project
it will be autodiscovered by pytest during running
The point using stuff like self.assetEquals
Or ASSERTEQ is mostly arraised from need to receive detailed debugging information in case of test failure.
Pytest is having good self reflecting capabilities to tell it just from regular assert
So not a really big point to use not just assert
Your meaning behind test is supposed to be expressed in test name
Well... Nothing forbids u from using some unittest features in pytest if that desiring though
not exactly unit testing, but how can I create a virtual envirome with a specifc Python version (using the venv module)
python3.10 -m venv venv
Write python subversion explicitly
Different tools help to manage multiple pythons...
pyenv makes easier having and installing multiple global Pythons
tox operates with venvs to run tests across multiple python versions.. as well as Github actions matrix
I gotta try tox in the future
btw, if I specify the python versions of a project in the PyPi classifiers, does pip install ... actually check for the latest compatible release for your Python version?
or is it like a view only thing
Not sure (it should not technically). Poetry surely does
Hey i want to make Unit Tests for my Celery tasks, this is what i have so far :
https://paste.mod.gg/sjqdffpsoppf/0
My app works well and adds CSV data to the database as proper models but how can i test the Celery tasks themselves?
How do i create valuable tests for myself?
Not sure if my current tests are even adding anything valuable... they pass, but are they actually doing anything lol
A tool for sharing your source code with the world!
Celery has special fixtures for testing it. Additional argument needs to be supplied for their auto import. There is somewhere micro-package that does it for you.
With those fixtures running... U will be having imitated running worker
When I LL be near PC i LL try to find some example perhaps
@maiden pawn thanks a lot, would be awesome! Celery works great doing the thing i want to do.
You mean pip-packages for Celery? I saw some cool ones but i'm never sure if they are good or not, only one way to find out i guess.
https://docs.celeryq.dev/en/stable/userguide/testing.html#pytest
Enabling
Celery initially ships the plugin in a disabled state, to enable it you can either:
pip install celery[pytest]
pip install pytest-celery
or add an environment variable PYTEST_PLUGINS=celery.contrib.pytest
or add pytest_plugins = ("celery.contrib.pytest", ) to your root conftest.py
official docs have pretty much mentioned stuff
def test_create_task(celery_app, celery_worker):
@celery_app.task
def mul(x, y):
return x * y
assert mul.delay(4, 4).get(timeout=10) == 16
This is quite easy to comprehend, thx!
Can i import the tasks.py to my test file instead of writing the same one inside my test function ? I guess yes ?
@river pilot are codes paths reached via multiprocessing.Process from pytest included in coverage automatically or do I have the set the environment variable and do the import from coverage in each subprocess?
Hello guys, I have this code:
class InfluxInterface:
def __init__(self):
self.__client = None
self.bucket_name = 'bucket_name'
def connect(self, url=IFDB_URL, token=IFDB_TOKEN, org=IFDB_ORG, timeout=IFDB_TIMEOUT, debug=False):
self.__client = InfluxDBClient(url=url, token=token, org=org, timeout=timeout, debug=debug)
def is_connected(self):
return self.__client is not None
def insert_stuff(self, stuff: List[Tag]):
if not self.is_connected():
return
points = []
for item in stuff:
point = Point('measurment_name').time(item.item_ts).tag('tag_name', item.tag).field('field_name', item.field)
points.append(point)
with self.__client.write_api(write_options=WriteOptions(batch_size=5000, flush_interval=5000),
success_callback=self.batch_write_success,
error_callback=self.batch_write_error,
retry_callback=self.batch_write_retry) as write_api:
write_api.write(bucket=self.bucket_name, record=points)
# Write is not returning anything (returning None)```
I want to unittest it using `pytest` . Of course I do not want to really call DB methods, so I am trying to mock `influxdb_client` parts and than check if they were called correctly.
This is how far I got with testing:
import pytest
from my_lib.influx_lib import InfluxInterface
class TestInfluxInterface:
def test_insert_stuff(self, mocker):
influx_client = mocker.patch('my_lib.influx_lib.InfluxDBClient')
# Is connected, return True
mocker.patch.object(InfluxConnector, "is_connected").return_value = True
test_connector = InfluxInterface()
fake_write_api = mocker.MagicMock()
test_connector._InfluxConnector__client = influx_client
test_list = [test_item_1, test_item_2, test_item_3]
result = test_connector.insert_stuff(test_list)
print(f'influx_client has calls: {influx_client.write_api.mock_calls}')
print(f'fake_write_api has calls: {fake_write_api.mock_calls}')
print(f'fake_write_api.write has calls: {fake_write_api.write.mock_calls}')
The result is this:
influx_client has calls: [
call(write_options=<influxdb_client.client.write_api.WriteOptions object at 0x7feb4885fa00>, success_callback=<bound method InfluxConnector.batch_write_success of <my_lib.influx_lib.InfluxInterface object at 0x7feb488527d0>>, error_callback=<bound method InfluxConnector.batch_write_error of <my_lib.influx_lib.InfluxInterface object at 0x7feb488527d0>>, retry_callback=<bound method InfluxConnector.batch_write_retry of <my_lib.influx_lib.InfluxInterface object at 0x7feb488527d0>>),
call().__enter__(),
call().__enter__().write(bucket='PYTEST123-bucket_name', record=[<influxdb_client.client.write.point.Point object at 0x7feb488507c0>, <influxdb_client.client.write.point.Point object at 0x7feb48850760>]),
call().__exit__(None, None, None)
]
fake_write_api has calls: []
fake_write_api.write has calls: []
However I do not know how to asset this: call().__enter__().write(bucket='PYTEST123-bucket_name', record=[<influxdb_client.client.write.point.Point object at 0x7feb488507c0>, <influxdb_client.client.write.point.Point object at 0x7feb48850760>]).
As you can see in prints, I have tried different mocks, but all the options I can think about were not working and I cant think of anything else π
So, does anybody have any idea how to assert it?
mock your DB fully and provide other application parts this mocked InfluxDB for testing. Write simple Actions interacting with db with simple input and output as pydantic models, that can be easily mocked, or something similar
see Porto for reference about Actions https://github.com/Mahmoudz/Porto , read Clean Architecture By Robert Martin as preqrequisite.
and besides that you can easily run tests for influexdb code itself if you will write participation of influxdb as docker https://hub.docker.com/_/influxdb
I have mocked the InfluxDB -> python interface influxdb_client. I am not interacting with DB in any way. I think I did it quite sucesfully (because even the context manager thing works). However, what I am asking is, how do I check if the mocked object contains this exact call:
call().__enter__().write(bucket=<my_bucket_string>, record=<my_record_object>)
This is how I solved it, not sure if its 100% correct tho (if it checks if the method is called exactly one time)
influx_client.write_api.assert_has_calls([call().__enter__().write(bucket=<my_bucket_string>, record=ANY)])
Also needed to add imports:
from unittest.mock import ANY, call which I am not happy about, because why do I need to import from unittest if I moved to pytest π
Sorry, didn't see your message until now...
no worries, it seems to be included in coverage? But on here it says
https://coverage.readthedocs.io/en/7.0.5/subprocess.html
If you have subprocesses created with multiprocessing, the --concurrency=multiprocessing command-line option should take care of everything for you. See Execution: coverage run for details.
so I wasn't sure if it meant multiprocessing.Process coverage wasn't supported or what
maybe i don't understand the specifics of the terms. Why wouldn't it be supported?
since pycharm didn't include the coverage in the in-line display unless I added https://github.com/ionite34/einspect/blob/main/tests/conftest.py#L32-L37
tests/conftest.py lines 32 to 37
import os
import coverage
os.putenv("COVERAGE_PROCESS_START", "1")
coverage.process_startup()```
but it seems included in the terminal report
so I guess maybe pycharm issue
not sure
Hey im trying to mock a Celery task but i cannot seem to return the value form the task but rather i get a MagicMock object:
from unittest import mock
..........
@patch('csvimport.tasks.upload_csv')
def test_csv_upload_with_celery(self, my_task_mock):
""" Tests the Celery background task by providing a csv-file with both valid and invalid row data"""
dirname = os.path.dirname(__file__)
# Upload Station to Celery
self.file_station = os.path.join(dirname, 'CSVFiles/Station_test_csv.csv')
self.csv_data_type_station = 'station'
self.upload_type = 'safe_create'
self.result_mock_upload = my_task_mock.delay(self.file_station, self.csv_data_type_station, self.upload_type)
my_task_mock.delay.assert_called()
self.assertEqual(self.result_mock_upload, '9 stations uploaded successfully')
self.assertEqual(len(Station.objects.all()), 9)
How can i get the return value rather than the object? Or do i even need the mock library can i just call the Celery task itself in the tests?
The command my_task_mock.delay.side_effect = '9 stations uploaded successfully' seems to return only the digit 9 i wonder why that is? GPT suggested using 'side_effect' to mock a return value
Wild guess, side_effect expects to be a list and interprets the string as a list of characters.
Why do you use side_effect and not return_value?
According to doc:
side_effect - This can either be a function to be called when the mock is called, an iterable or an exception (class or instance) to be raised.
return_value - Set this to configure the value returned by calling the mock:
source: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.return_value
GPT is language model, not technical, there is a reason why StackOverflow does not accept advices from it π
So much hype over it over it taking over our jobs but at intermediate level it starts spitting wrong answers
Anyhow, so return_value is the thing i should use?
Still havent figured out exactly how to use Celery with mock, let alone what exactly it does.. i just want to emulate an async task in the test env
Well, I would try it with return_value, I am using it for my unitests pretty often. side_effect really is mostly for the raising exceptions. But I do not know what Celery is, so my advice might be off.
Ah well i appreciate ur input, its good to know the general idea of the methods. To be clear, isnt mock just kindof for running an βoffline copyβ of the func ur wrapping in the decorator?
Celery is for running tasks asynchronously with Redis or such
I wouldn't say mock is a "offline copy", in my understanding mock is more like a black box that accepts anything u give it, and returns whatever u set it to return (it does not have internal structure of the mocked object, thats why I do not consider it "copy"). You can set mock to behave totally differently than the object you mocked, which is of course very bad example and approach, but it is possible. π
The use of autospec changes that. With autospec it should be closer to the mocked object. But I do not consider myself to be expert in this field, so do not take my words without confirmation or testing please. π
Cool! I have to find out more tho! Is there anything that comes to mind regarding testing the db?
The issue is that my test data gets added to the real db for some reason only when i use Celery.
But yeah dont worry about this, thank for your help
When I use library with DB (which I do right now), I have completely mocked the DB interface library (psycopg2 in case of Postgres, or influx_client in case of InfluxDB).
The basic idea is, I do not do any calls on DB, I call the method I want to test, and than check mock, if the DB cmd was called right.
For example, you have method to extract some data from DB. The method has argmuents, like date_from, date_to, etc.. and it should use those input data to create correct SQL command. What I do in this case is, that I test, if tested method called right SQL command. And thats it. Rest is out of your score (you are not supposed to test if psycopg2 messed the command, or if DB engine represent the given command wrongly) :).
If the method calls one SQL command and than use result for another command. Than u mock the call, give it return_value so it does not interact in DB.
In fact, if you use some code check on git server, its usually not even possible to have DB there, so your unittests must be able to work without DB.
Yeah seems smart! What should i use for SQLite or MySQL?
So another issue, what do i need to use to test the JavaScript in Django templates? Like i have a JSmap i want to check if its rendered with the correct data
Its same, just mock the library u use to work with DB.
Do i use webdriver to test JS?
Does anyone have any good project ideas to practice TDD?
Literally any project u wish to implement. U need to do what is fun to you.
Testing will be needed in any project anyway
i have one question about context manager. This is my code:
from path.lib import DBInterface
class MyClass:
def __init__(self):
self.something = "something"
def _my_method(self, some_key, new_setup):
with DBInterface(self.something) as ic:
current_setup = ic.get(some_key)
if current_setup != new_setup:
with DBInterface(self.something) as ic:
ic.set(new_setup)
def public_method(self, some_key, new_setup):
return self._my_method(some_key, new_setup)
class TestMyClass:
def test_extractor_register(self, mocker):
fake_db = mocker.patch.object('my_path.my_lib.DBInterface')
fake_db.get.return_value = None
spy_obj = mocker.spy(MyClass, "_my_method")
test_class = MyClass()
# Test new registration in _extractor_register
result = test_class.public_method(Tconf.test_key, Tconf.test_key_setup)
spy_obj.assert_called_with(ANY, Tconf.test_key, Tconf.test_key_setup)
assert result.result_status.status_code == Tconf.status_ok.status_code
assert result.result_data == MyMethodResult.new_reg
How do I properly mock DBInterface so it does not interact with DB?
What I want to do is:
1.) Mock whole DBInterface so no DB operations are being made
2.) Set return value to DBInterface.get() so it returns exactly the value I need for next logic
3.) Check if ic.set() method was called with proper argument
The problem is, calls of the fake_db looks like:
[call('something'),
call().__enter__(),
call().__enter__().get('test_key'),
call().__exit__(None, None, None),
call().__enter__().get().__ne__('anything'),
call('something'),
call().__enter__(),
call().__enter__().set('test_key', 'test_key_setup'),
call().__exit__(None, None, None)]
a.k.a. it is in context manager, so setting fake_db.get.return_value = None throws exception that method is not called.
https://docs.python.org/3/library/unittest.mock.html#mock-open
Using open() as a context manager is a great way to ensure your file handles are closed properly and is becoming common:
with open('/some/path', 'w') as f:
f.write('something')
The issue is that even if you mock out the call to open() it is the returned object that is used as a context manager (and has __enter__() and __exit__() called).
Mocking context managers with a MagicMock is common enough and fiddly enough that a helper function is useful.
>>>
m = mock_open()
with patch('__main__.open', m):
with open('foo', 'w') as h:
h.write('some stuff')
m.mock_calls
[call('foo', 'w'),
call().__enter__(),
call().write('some stuff'),
call().__exit__(None, None, None)]
m.assert_called_once_with('foo', 'w')
handle = m()
handle.write.assert_called_once_with('some stuff')
Googling python how to make context manager is not bad idea
sorry, bud that does not solve any of my questions
- This is example above how to mock context manager. This solving your first problem
- example shows how to check how many times stuff was called
- for this problem check official documentation by the same link, they have example in Mock/MagicMock, which u can return from mocked manager
As I understand that article is, that mock_open() is a mock for that one exact context manager. For builtin open() method, not for any Context Manager.
Anybody can create his own custom ContextManager class that does different stuff not opening file. Thats SBInterface in my case.
One use case for this is for mocking objects used as context managers in a with statement:
>>>
mock = Mock()
mock.__enter__ = Mock(return_value='foo')
mock.__exit__ = Mock(return_value=False)
with mock as m:
assert m == 'foo'
mock.__enter__.assert_called_with()
mock.__exit__.assert_called_with(None)
Mock object supports mocking context manager
A matter of overriding correct dunder methods

@quasi olive if they have just html/css rendering, then you could use just Session requests of Requests library in pytest
otherwise u need to use Selenium or its alternatives
you can use it in pytest too π
Iβve tried selenium before
some people like Robot framework for this. I find it horrible
But I never had a goal so I might have a go at it
session requests not will always work but better, because they are more lightweight
they will give different testing results though
with session requests -> you are directly hacking web site by requesting its endpoints (for most of part imitates like it interacts like user though)
it may be not something u a asked to do
selenium interacts with GUI in full scale
I see
Might be better to use selenium then
The weight of it shouldnβt be too bad so long as it doesnβt break
technically Requests library imitates user too, just at 80%... percent (when u use sessions)
only javascript should be missing from its ability to see
considering that u deal with Java web site, it could be enough
Requests library is more preferable because it is 10 times lighter than selenium
Sucks that chromedriver doesnt seem to work in splinter or Selenium, i really would like to test some basic JS functionality
using requests rn, the endpoint i'm looking for isn't a link, but it's a javascript pop-up after getting to aforementioned link... 
well, Selenium it is.
I know that, but how do you do it in the case I posted?
I was trying many variations, and I am always getting mock itself returned, instead of value I set..
fake_db.get.return_value = None
fake_db.__enter__().get.return_value = None
fake_db.__enter__.get = Mock(return_value=None)
mocker.patch.object(MyClass.DBInterface, "get").return_value = None
neither of that works.
And to be honest, the example you gave:
mock = Mock()
mock.__enter__ = Mock(return_value='foo')
mock.__exit__ = Mock(return_value=False)
with mock as m:
assert m == 'foo'
mock.__enter__.assert_called_with()
mock.__exit__.assert_called_with(None)
The ContextManager is called there in test_* method. But in my case, the ContextManager is called inside of the method I am testing.
So, the example you gave me looks to me completely different than what I am asking about.
The ContextManager is called there in test_* method. But in my case, the ContextManager is called inside of the method I am testing.
So, the example you gave me looks to me completely different than what I am asking about.
you can use unittest.patch function with having as input created Mock for context manager to put it inside without having direct access
it is not the best course of action though, you are supposed to rearrange code architecture for having direct access for mocking object though. Making database somewhere included as Composition, and overriding it
can I ask for some code example? not sure if I understand
I found it..this is th correct answer:
fake_db.return_value.__enter__.return_value.get.return_value = None
I've been away for a while.... if I want to make nice HTML reports of my pytest results, is pytest-allure still the best choice?
No idea about html, but since u use pytest, i can say u are already on the right path π
say i have a pytest function that i'm using to test some functionality in my python code, like
def test_foo():
# stuff
i now realize that i want to make a second test that is very similar to this one, but i don't want to duplicate code. therefore, i want it to take an argument like
def test_foo(bar):
# stuff that depends on boolean bar
and then when i run pytest i want to specify the value of bar. How do I achieve this?
chatGPT seems to be suggesting that this is not possible in general with many test functions
nvm google saved me
You could use a fixture if they share a common setup code
yeah i realized you can just use fixture and then call pytest with -k [True], or -k [False]
Not sure what you want to do here
If you want to call your test with both True/False you can just parametrize it
Hi folks, i am long time pytest user but i our company we had a talk about unit testing and decided to use unittest mainly because i was unable to found any logical argument agains. Now i am getting kinda anoyed becuase in unittest everything is a bit slow to make, hackish etc and everyone seems to use pytest because i can't found any reasonable videos about unittest. Can you point me in a right direction for some argumetns against unittest module? Thanks!
Unittest is kind of outdated (in my opinion), for me main advantage of pytest is are modular fixtures, and ability to structure your tests how you need
e.g. functions, class methods
Yup i have the same feeling here, everything is kinda rusty and slowish.... also i am unable to find any reasonable configuration that can be put into pyproject.toml, pytest supports configuration from pyproject.toml
Asserts are also easier to write, but it's not that important imo
It is not but hey.... much easier to write assert result == True than self.assertTrue(result)
assert result is True π€¨
whatever π
but yea
modular fixtures are great but what exactly do you mean with structure how i need? The same tests can be written in both suites pretty much in the same fashion except in unittest you have to write much more balast code
For some tests it makes more sense to use classes, for example if you want to test an inherited object and run same test suite on it
What's your main problem with unittest though? I only used it for a bit, since I quickly switched to pytest
For now inability to specify where the code is without hacking into sys.path in each test file and too much balast code for simple tests.
For now inability to specify where the code is Hm, what do you mean? π€
Can't you just import it?
My project structure looks like this
So, same as mine π
and for pytest i use following configuration in pyproject.toml
[tool.pytest.ini_options]
minversion = "6.2"
addopts = "-v --no-header -s"
testpaths = [
"tests"
]
pythonpath = [
"src/auth_lib"
]
I would just import from auth_lib honestly
in pytest it works well.... but i am unable to make it work in unittest
Then don't π
I am kinda required unless i found some good arguments to say no to unittests π
Required by who though?
By my decisions? π I have to put good aruments on the table to switch whole company (approx 10 people) to start using pytest because they are used to unittest. And yea they have even hard time to understand how to write tests.... i had a whole day educational talk about decoupling so we can really start using tests.
Pytest tests are easier to write - no convoluted methods like assertTrue, assertEquals, etc, just assert
You can create test by just prefixing it with test_
Pytest just has a bigger set of features like fixtures and parametrization
Pytest can still run unittest tests too
that's a great argument tho!
Also there's a lot of pytest plugins, for example we use pytest-django
We can switch old tests to pytest and rewrite them over the time.
Yep
Because i finally pushed people to stop copying common code and put repeated stuff into private pipy libraries which mean we will rewrite lot of code soon.
For me it's a lot easier to use pytest, just because of the modular fixtures:
async def test_healthcheck(http_client: AsyncClient) -> None:
response = await http_client.get("/health")
assert response.status_code == status.HTTP_200_OK
assert response.json() is None
I can provide everything I need in my test
And you can have fixtures local to a file and specific submodule too
Yup... the only thing is you can't iterate over multiple fixtures π
No i mean something like run the same test on good mock, bad moc, milicious mock etc....
One major limitation of pytest fixtures is that you can't run test dynamically multiple times using it... technically there's a param argument that would run tests that depend on it multiple times:
@pytest.fixture(scope="module", params=["smtp.gmail.com", "mail.python.org"])
def smtp_connection(request):
smtp_connection = smtplib.SMTP(request.param, 587, timeout=5)
yield smtp_connection
print("finalizing {}".format(smtp_connection))
smtp_connection.close()
But if you want to fetch these parameters based on some other fixtures it wouldn't work, you'd have to do what on test level
But it's still possible to use "static" content of your program, like enums in here
Yep thats what i am talking about. You canot simply iterate trough params with items loaded from mocks
If you're talking about mocking methods - I'd usually avoid that
But if you need to test code that interacts with network that's usually unavoidable
@pytest.fixture()
def mock_requestor():
return MockRequestor(dict(
valid_session_id=UUID('4c8dcb79-0625-49e0-8ac7-3f512eed5f4e')
))
something like this in conftest.py
You should also try poetry or pdm instead of pipenv π€
or did they add support for pyproject too?
Not sure i will take a look soon. I been hired to improve python quality in this company and they use pipenv so we use it now also because all build tools etc are made for pipenv but i am plannign to check posibilities π
You should try to introduce different formatters and linters too then
Yup, we trying on current project flakeheaven
But still i would like to find a option for autopep
Maybe try ruff?
What is the major reason for ruff?
Very fast, implements a lot of checks from various tools and flake8 plugins
Mkay, appending it to list of things to try out π Thanks
I am trying to unittest method that uses this query() method of influxdb_client: https://github.com/influxdata/influxdb-client-python/blob/dc95257c6f1d84cb14c1b120faaef37ef1e0da30/influxdb_client/client/query_api.py#L127
However, I do not want to DB calls (and honestly, cannot do it because of env on git server where unittests are being run).
So, I am mocking the call, and setting it return value. Which I have done and its working, the mocked method will return whatever I want, BUT I need it to return the same object as original method return, becuase, I want to test parsing of it too.
When I was going through source code of the returned object of original method, i feel like getting deep into rabbit hole. Is there any simple way how to do create custom objects with complex structure? Maybe mock lib has some tools for it? π
influxdb_client/client/query_api.py line 127
def query(self, query: str, org=None, params: dict = None) -> TableList:```
Is there a library or any pattern that can help me mock out a complex nested object from a json schema?
I basically have an internal API with a client I'm trying to mock responses from, and they return actual objects that I expect to interact with, I'd prefer to store this in json or yaml rather than setting them up in code
Got pytest-httpserver recommended to me. Not exactly the approach I was looking at, but will accomplish the goal!
@gray kelpthanks what you said worked (python -m pytest)
Why does my expected failure test show up as an xpassed? Is there a way to make it show failed instead? VSCode also shows it as a passing test
What tools are y'all using for testing your HTTP-based services?
Depends on what framework you're using π€
WSGI and ASGI apps could be tested using httpx client for example
Starlette TestClient uses it IIRC
But in most cases you can just use it directly
Well, I was looking for some generic tools
like, IIRC postman has some API testing stuff
I thought you were talking about unit/integration tests π€
hmmm
define unit test and integration test π
Integration test would test system as a whole (e.g. making an http call to an application, probably involving db or other services π€, at least in my understanding)
well, yeah, using HTTP calls to test some behaviour
Unit tests aren't applicable here, but you'd usually write them too
Why won't httpx be a generic tool? You can test remote API's or "local" python ones
I suppose yeah
I didn't use postman personally, but for testing pytest+httpx would be perfect
Your tests can be fully contained within your application code and be run in CI
currently I'm using aiohttp and pytest-aiohttp
What are you testing?
wdym?
yeah
I actually have no idea what I'm doing, just generally surveying as to what I should use
What framework are you using?
I could write a simple snippet of how you could create an http client for it
for the app? aiohttp
I already get how to write tests for it, I'm just wondering if there's anything "industry standard" I'm missing
Didn't know aiohttp doesn't support asgi nor wsgi π€
ye
well... not sure how big of a problem it is
ASGI basically means... you're using your application + uvicorn
ASGI is just a common interface
You can use any server that supports it
Honestly pytest-aiohttp should just work
Anyone used dirty-equals? https://dirty-equals.helpmanual.io/
what's your opinion/experience?
Looks like not a bad idea.
Except very bad and scary name π€£ (and logo)
well, if my code is shitty, why not use shit libraries
To be honest I don't exactly seeing benefit of such library
Pydantic model will ensure string is a string
Or positive and etc
No point to test library code
This shitty equal is not bringing a lot of usefulness
Usually people need to test exact matches in code
If you're testing responses from your api I'd test for types too
If you return an int, it should be an int
Not a string π€
wdym 
So you propose to make a new class for every test case?
Maybe I just didn't read the docs π
I wouldn't use that library if you can avoid that, since you should know what your api returns
Deserializing responses to pydantic π
That's not the usecase for that library
Essentially FastAPI uses it for this already, for input and output
I meant dirty-equals
I mean using pydantic fot deserializing, instead of installing dirty-equals
@fiery arrow If we take example from docs:
# user_data is a dict returned from a database or API which we want to test
assert user_data == {
# we want to check that id is a positive int
'id': IsPositiveInt,
# we know avatar_file should be a string, but we need a regex as we don't know whole value
'avatar_file': IsStr(regex=r'/[a-z0-9\-]{10}/example\.png'),
# settings_json is JSON, but it's more robust to compare the value it encodes, not strings
'settings_json': IsJson({'theme': 'dark', 'language': 'en'}),
# created_ts is datetime, we don't know the exact value, but we know it should be close to now
'created_ts': IsNow(delta=3),
}
Everything here can be read from db and compared to what api returned to you
Btw. Funny joke. We all three share same native language but aren't speaking in it π
So, why would you for example write "id": IsPositive instead of using user id? "id": user.id
It's basically a library of stuff like
class CloseTo:
def __init__(self, value, diff=0.01):
self._value = value
self._diff
def __eq__(self, other):
return isinstance(other, (float, int)) and abs(self - other) <+ self._diff
``` so you can write tests like ```py
assert api_response == {"ok": True, "warehouse": {"goods": [{"type": "bananas", "weight": CloseTo(42.69), "potassium_contents": CloseTo(0.5}}]}}
``` instead of ```py
assert isinstance(api_response, dict)
assert api_response.keys() == ...
...
For that you have pytest.approx 
well, it was just an example
Just don't misuse it, library itself seems to be nice
actually in my use case I'm fine with match
async def test_on_table_addition_an_empty_table_is_created(api: TestClient):
creation_resp = await api.post(
"/api/tables",
json={"name": "Ducks"}
)
assert creation_resp.status == 200
match await creation_resp.json():
case {"answer": {"table_id": str(table_id)}}:
assert not ({*"/&?=+"} & {*table_id})
table_resp = await api.get(f"/api/tables/{table_id}")
assert table_resp.status == 200
assert await table_resp.json() == {
"answer": {
"table": {
"id": table_id,
"name": "Ducks",
"columns": [],
"rows": [],
},
},
}
case wrong:
assert False, wrong
although it's uhhh nesty
If you're testing API I'd make a separate module (file) for each operation:
# test_post_create.py
async def test_should_be_authenticated(): ...
async def test_invalid_title(): ...
async def test_ok(): ...
And test for various properties of your endpoint in different functions
well, I want to test how the endpoints interact with each other, BDD style
For example to create a post:
- User should be authenticated
- Title should be of some specific format
- Endpoint should return 200 ok, persist data in db and return that post if everything is ok
right now I don't even have a database, I want to be able to change that easily
because I'm not sure what kind of storage I want
They shouldn't interact with each other really
Can't go wrong with SQL
actually I was considering using an event sourcing approach, since I will need to a version history feature
If you want you can abstract storage logic into repositories, but only if you really need that
I just use sqlalchemy everywhere, without abstracting it
Well, they provide an interface to some application, and I'd like to see how the application behaves. I don't care about the implementation details (like the database) at this level of test abstraction
It's like mirroring each method in a class with a test. If your class represents a state machine with invariants between methods, it won't go too well
Shouldn't you test the interface itself (the API) instead of testing that app? π€
From my understanding they most likely should be tested separately
consider these "end-to-end tests"
I want to test some broad scenarios that slice through the whole application
We don't do that here
well... it's more of an exploratory end-to-end testing
I'm trying to figure out what the application will need to do. and maybe I will scrap them
why?
To be honest end-to-end test are most complicated to figure out how to setup and write
If you didn't add any error monitoring yet your time would be better spent adding error monitoring tool like sentry to your project(s)
Actually I don't have any code on the project yet. I'm doing a bit of a... cursed experiment
Add sentry anyway 
anyone have a good link to learning unit tests including mocking apis? Every article I am finding online says different things and I am looking for something detailed and consistent. tyvm
Hi, so I'm trying to find out how much memory my unit test is consume, as I seem to have a memory leak somewhere, and we working on a constrained edge device. Tried valgrind to debug, but it doesn't seem to give useful info, is there any profilers for python specific that would be great ? it's on a linux edge device...