#unit-testing

1 messages Β· Page 25 of 1

knotty rover
#

I want to test the bubble sort function in the code and I am unable to mock the data!

#

def sort_bubble (df):
n = len(df['Total Cases']) - 1
s = df['Total Cases']
# Traverse through all array elements
for i in range(n, 0, -1):
for j in range(n, n - i, -1):
if s[j] > s[j - 1]:
df.loc[j], df.loc[j - 1] = df.loc[j - 1], df.loc[j]

return df
ember maple
fiery arrow
#

I wrote a class, and all the class is doing is implements authentication via GitHub. What would be the best approach to test it?
Monkeypatching aiohttp seems like a lot of work, and using dependency injection also seems a bit redundant because all the class is doing is interactive with the outside world. Should I just not write any unit tests for it, and leave it to integration tests?

maiden pawn
# fiery arrow I wrote a class, and all the class is doing is implements authentication via Git...

Situations like this I usually approach as...

  1. if other tests have dependency on this test, I make dependency injection, if this dependency is slow to speed up other tests, or if I am not 100% sure that it will not break in other tests. Otherwise I could go without injections.

and at the same time I always have left integration test
2) that checks only this thing works properly without injections

fiery arrow
#

Well, I can't really run it without injecting/mocking because it uses secrets from configuration and such. and I don't want to bombard Github with a 1000 requests

#

now that I think about, mocking what I need in aiohttp isn't that bad

maiden pawn
#

if I can...

#

if this this makes only one request

#

that I can wrap in my tests to particular case...

#

I use vcr

fiery arrow
#

vcr?

maiden pawn
#

first time it makes real request

#

then saves interactions into file

fiery arrow
#

ah

maiden pawn
#

then uses saved file for all other repeated invokations

#

it is requiring literally only one function to use

#
import vcr
with vcr.use_cassette("unique_file_path_for_this_request.yaml"):
  your_request()
fiery arrow
#

I still have the issue of requiring real github credentials. If I understand what unit tests are for, they should just test the logic behind my code, right?

maiden pawn
#

at least import requests library is caught well

maiden pawn
#

integration tests check your interaction with dependency... which can be github, filesystem, database, or just library out of your control

#

technically... things within your control database/filesystem/your own other microservices are still part of unit tests in my opinion, at least if your keep those dependencies deployed with devops tools, which means this infrastructure remains part of your code

#

real integration tests check dependencies which are totally out of your control, github, third party applications

#

there is also third test category, which goes for end to end testing

maiden pawn
#

github/gitlab piplines can be filled with stored SECRETS if necessary

#

situation becomes a bit more troublesome, if credentials look like a big file though

fiery arrow
#

I decided to give up and just not write any unit tests for this πŸ‘

maiden pawn
elder relic
#

Is anyone familiar with PyTest? I'm trying to develop a habit of building more unit tests into my projects, and there's a class that I have created with a single method. I want to write unit tests for them, but I just need a bit of help thinking about what would be something that should be tested.

#

I'm thinking that I could share the code, and then we can discuss what would be good to test, then I can figure out the implementation in PyTest on my own

ember maple
#

@elder relic please write out your questions ^^

elder relic
# ember maple <@!733850772089077862> please write out your questions ^^

Sure. My question is, from this code that I have below, what are some things that I can think about when trying to write out my unit tests? I don't really understand what it is that I am testing for, so hopefully that's enough to get started:

from pandas import read_csv

class StackOverflowDataFrame(pd.DataFrame):
    @property
    def _constructor(self):
        return StackOverflowDataFrame

    def find_multi_response_columns(self, delimiter):
        survey_data = self.copy()
        columns = survey_data.columns

        multiple_response_columns = []
        for column in columns:
            for response in survey_data[column]:
                if type(response) is str:
                    if f"{delimiter}" in response:
                        multiple_response_columns.append(column)
                        break

        return multiple_response_columns


path = r"C:\Users\djgra\Desktop\developer_survey_2020\survey_results_public_2020_sqlready.csv"

df = StackOverflowDataFrame(read_csv(path))
#

So the class isn't super complicated. I am subclassing pd.DataFrame and then my methods do some particular processing. So I want to try and begin to get myself thinking about what good testing looks like, because I have never written tests before, I normally just reason about my code.

ember maple
#

my first suggestion would be to not use a own class, just have a helper function

#

then in a unitest, yo ucan just invoke that helper

elder relic
#

Like for the purposes of testing, write things in functions?

golden sail
#

#medical history
print("Get to know ur patient's medical status with this tool")
patient = "Ur patient's"
stool_colour = input(f"Question 1 : What is the colour of {patient} stool (poop)= ")

Urine_colour = input(f"Question 2 : What is The colour of {patient} urine: ")

Blood_glucose = input(f"Question 3 : What is {patient} blood glucose level? = ")

if stool_colour == "dark yellow" and Urine_colour == "pale yellow" and int(Blood_glucose) <= 120 and int(Blood_glucose) >= 80 :
print("patient is normal. Have a good day!")
else:
print("Your patient isnt well.")

#

I am new to python

#

so any mistake please inform

elder relic
ember maple
elder relic
elder relic
#

Because I think that with unit tests, we want to make sure the individual functions are working as we expect them to, right?

ember maple
elder relic
#

Let me see if I can expand on that a bit further. So my helper function extracts all of the columns that are classified as "multiple_response_columns". For the sake of example, let's suppose I know for sure that there are 7 columns that satisfy that condition, and maybe I know this because I have looked at the original data or something.

#

So in this instance, I would pass the helper function a dataframe and then assert that the number of columns is 7.

#

I appreciate the patience by the way

ember maple
pearl cliff
#

as for the question about testing this logic in general: figure out some "invariants" that must always be true for any input

#

leaving aside possible refactorings, your tests could look like this:

  1. randomly generate a dataset full that meets certain properties
  2. run your code on it
  3. assert that the output is what you expect, given the properties of the input
#

for example, you can randomly choose from the delimiters ,, ;, |, and maybe other weird ones. then you can use the test assertion that the number of columns is exactly what you expect.

#

generate a table of column names and data types, generate fake data with those types, then assert that the resulting dataframe has those same column names

#

in python we have the excellent Hypothesis library to help write these kinds of tests https://hypothesis.readthedocs.io/en/latest/ (specifically, it helps generate the fake data and gives you some debugging and introspection tools)

#

not related to testing: write isinstance(response, str) instead of type(response) is str. there are good technical reasons to prefer the former.

#

i agree though, i really don't think this should be a subclass of a dataframe

#

is this really a "new type" of object? or is it just a helper function?

#

and what's with the _constructor property?

#

or is that a pandas internal thing that you're expected to override when subclassing?

elder relic
#

It's a pandas internal thing. So there's two reasons why I chose to write this as a class.

#

The first is that I wanted to get some experience working with classes. The second is that my workflow down the road ends up getting kind of complicated because of the procedures I need to perform on the data.

#

So my thinking was that I could segment my workflow into different phases via classes and try to make the code more modular as opposed to just having a ton of different functions.

pearl cliff
#

i see no reason not to have standalone functions like this:

def is_multiple_response_value(delimiter: str, value: object) -> bool:
    return isinstance(value, str) and delimiter in value

def is_multiple_response_column(delimiter: str, data: pd.Series) -> bool:
    return any(
        is_multiple_response_value(delimiter, value) for value in data
    )

def find_multiple_response_columns(
    delimiter: str, data: pd.DataFrame
) -> typing.Sequence[str]:
    return [
        colname
        for colname, series
        in data.items()
        if is_multiple_response_column(delimiter, series)
    ]
elder relic
#

Hmm, yeah I mean I don't either haha

pearl cliff
#

i would offer that subclassing will make your life harder, not easier

#

if you want to practice with classes, implementing a scikit-learn estimator or transformer is a great exercise

elder relic
#

I appreciate the feedback. Maybe I will just work on making the helper functions I already have written a lot better.

#

If two of you are saying the same thing, and I presume you guys are well versed in the language, then i'll take your advice.

#

One thing though - why do you explicitly have the datatypes in the functions? Is it just for clarity?

#

(btw, this is a very productive conversation, so thank you)

pearl cliff
#

keep in mind that the main benefits of classes are:

  1. encapsulating mutable state - database connections, state machines, arrays of numbers, etc.
  2. keeping "records" organized - e.g. a Person with an age, name, etc.
  3. implementing interfaces and single dispatch

defining a new class like DataFrame makes sense because there is a lot of internal state being encapsulated. if your StackOverflowDataFrame does some kind of internal magic that automatically dispatches to this or that helper function when a "multiple response column" is encountered, but that otherwise acts the same as a DataFrame then maybe yes you want to subclass DataFrame. this is because DataFrame (informally) adheres to a certain interface, and you might want your StackOverflowDataFrame to adhere to the same interface.

but this is not something i'd use or encourage for data analysis workflows, because it makes it harder to see what's going on. in an "application", it might make sense.

pearl cliff
elder relic
#

I'll take a look into them then, perhaps I can try to integrate them more into my work.

#

Because right now, as you can tell, I do not.

pearl cliff
#

i use them everywhere in "production" code. however they can be too verbose to use in "interactive" or exploratory work

#

that's one disadvantage of python compared to other languages that have a static type system built in

elder relic
#

Yeah, it is as if you are trying to bring static typing into Python, which for me is something I wouldn't have thought much of. I know Java is like that, and same with Go, I think JS as well but I am not sure.

pearl cliff
#

it's not always possible (there are a lot of limitations compared to a true statically typed language), but if you can write your code to pass mypy --strict then you can rest assured that you have prevented at least one entire category of errors

elder relic
#

Solid. Well, I will take this conversation, sit on it a bit, and rewrite some of the code I have and try to implement some tests. If I have troubles, i'll come back in a few days and reassess.

#

Appreciate all the help, and your patience.

pearl cliff
#

one last thing that's more specifically about testing: helper functions tend to be easier to test than classes with instance methods, in my experience

signal hollow
#

Hello everyone, I'm new here so I'm sorry if I'm in the wrong channel.
I've a question, what's the pythonic way to check the input of a method ?

proper wind
#

Is there a way to execute a teardown after all other tests have run? Currently I have created a setUpClass and used tearDown instead of tearDownClass, as I understand the class-methods will run before all tests, which is fine for the setup, but not the tearDown. However, I'm not sure if tearDown run after all tests are done or after each tests?

#

To illustrate if my testfile has the following setup:

class TestClass(TestCase):
  @classmethod
  def setUpClass(self):

  def tearDown(self):

  def test_1(self):
  
  def test_2(self):
#

my problem is I have setup some sql queries in the setUpClass, and say I use a particular query in test_2, but in my tearDown i delete it.

shrewd kraken
#

Possibly you want to run setup before each test?

#

Then teardown each test?

#

To keep tests seperate

pearl cliff
low pagoda
#

I am using pytest and I don't know what to do when tested function raises an exception.
I can mark test as @pytest.mark.xfail(raises=...) or use pytest.raises(...)

with pytest.raises(...):
  ...

Is there a reason when I should mark as xfail over using pytest.raises? Or maybe should I prefer pytest.raises?

pearl cliff
#

@low pagoda pytest.raises specifically asserts that some code raises an exception https://docs.pytest.org/en/latest/reference/reference.html#pytest.raises, while pytest.mark.xfail marks that a test is expected to fail https://docs.pytest.org/en/latest/reference/reference.html#pytest-mark-xfail-ref. i would prefer the former for testing code, and the latter for managing the test suite itself, e.g. some part of the test harness is unavailable and you want to just skip the test in that situation.

proper wind
#

the problem is this

#

currently what i've shown mean the calls are as such:
setUpClass called
test_1 called
tearDown called

test_2 called
tearDown called

#

If i have a query in setUpClass that is used in test_2

#

it won't be tested before it's deleted

#

tearDown is on function afterall

pearl cliff
#

@proper wind i think you just need tearDownClass instead of tearDown

bitter wadiBOT
#

@silk ridge :x: Your eval job has completed with return code 1.

001 | How old are you?: Traceback (most recent call last):
002 |   File "<string>", line 18, in <module>
003 |   File "<string>", line 3, in __init__
004 | EOFError: EOF when reading a line
trim laurel
#

Etf

proper wind
#

hi how you guys make your selenium undectectable.

pearl cliff
opaque echo
#

when using !pypi coverage
how do i set what threshhold of % covered when to fail

#

!pypi coverage

bitter wadiBOT
opaque echo
#

ah nevermind found it of course use the --fail-under=PCT

fiery arrow
#

how "DRY" should my tests be? I feel like if I'm extracting literals away from the test, they become hard to read

opaque echo
#

usually as much as makes sense, usually literals and their constant variables are very similar in naming so shouldn't be that hard to read if that is what you mean
HELLO_WORLD_MSG="hello world!"

pearl cliff
#

my tests tend to be "wetter" than the code itself

opaque echo
#

yeah, though still better to be DRY but definitely not nearly as strict as the code itself

fiery arrow
# opaque echo usually as much as makes sense, usually literals and their constant variables ar...

For context, I'm writing tests for a web API, and it seems to me that they are really long and drawn out ```py
@pytest.mark.asyncio
async def test_authenticated_user_can_delete_their_own_post():
auth_provider = FakeAuthProvider()

content = PostContent(
    "The title",
    {"foo", "bar", "baz"},
    [Header("a header"), Paragraph("some text")]
)
post = Post(42, User("Bob", "Bob B.", "bob.png"), content)
post_repo = FakePostRepo({
    42: post
})
endpoint = PostsEndpoint(post_repo, auth_provider)
client = TestClient(endpoint.app())

token = await auth_provider.log_in(AuthUser("Bob"))

headers = {"Token": token.content}

resp = client.delete("/42", headers=headers)
assert resp.status_code == 200
assert await post_repo.all_posts() == []

```, and it's getting progressively worse when I need to include more data. So I'm wondering whether there's a good way to create a library of fake data (like Posts here) to reuse it, without forcing the person reading the test to constantly jump back and forth

#

PostsEndpoint is the actual thing I'm testing, it's an ASGI app that represents a "branch" of my application

#

TestClient comes from Starlette

opaque echo
#

ahh so you want to know how/if you should have separate functions to create a mock content, post, post_repo, etc. object rather than clutter it here

fiery arrow
#

I was thinking of creating fixtures with several data sets

#

but the thing I'm worried about is that you'll need to go back and forth between the definition of the dataset and the actual test

opaque echo
#

yeah, that is kind of preference, in this case I don't think needing to know all of the details of for example the post content is necessary to the test but up to you here

fiery arrow
#

I think I'd prefer just copypasting some common bits, for the benefit of tests being painfully obvious

#

well, unless something is repeating in all tests

opaque echo
#

yeah, that is perfectly fine

#

readability/understandabililty is definitely important in code

fiery arrow
#

also... I can imagine the pain I would need to go through if I also needed to wrap the function in monkeypatching decorators

#

and patch asyncpg and Github's OAuth server here

opaque echo
#

no pain no gain πŸ˜‰

pearl cliff
#

your IDE gives you warnings for repeated code?

#

what's an example

#

yeah this is just the nature of testing, ignore your IDE

#

but if you want, you can abstract this to a separate list of moves and expected generated moves

#
class TestGeneratedMoves(TestCase):
    self.test_data = {
        'black king possible move into pawn check': (
            [((1, 1), King("BLACK")), ((1, 2), Pawn("WHITE"))],
            (1, 1),
            {(0, 0), (1, 0), (2, 0), (0, 2), (1, 2), (2, 2)},
        ),
        'white king possible move into pawn check': (
            [((1, 1), King("WHITE")), ((1, 0), Pawn("BLACK"))],
            (1, 1),
            {(0, 0), (1, 0), (2, 0), (0, 2), (1, 2), (2, 2)},
        ),
    }

    def test_generated_moves(self):
        for label, (piece_positions, start_coordinates, expected_moveset) in self.test_data.items():
            with self.subTest(label):
                board = Board(_length=3)
                for coordinates, piece in piece_positions:
                    board.put_piece(coordinates, piece)
                actual_moveset = generate_move(board=board, from_coord=start_coordinates)
                self.assertSetEqual(actual_moveset, expected_moveset)
#

of course you might prefer using some kind of GeneratedMoveTestData dataclass instead of a tuple, but it's the same idea

proper wind
#

Hey, i am trying to make a tester for my API, just a simple one that calls the URL and query

#

i keep getting stuff which involves initialization of .db (which i assume is database), does any tester need this?

#

and i dont have a database really, i am using someone else's

fiery arrow
#

@proper wind What framework are you using? Can you show the test code and the error?

proper wind
#

i was out running some errands so i can now

#

im using flask API

#

i want to test queries and calls for my API, but sofar all i got from unit testing online is basic funcion testing using py tester

timber widget
#

Potentially

rapid nova
# proper wind i keep getting stuff which involves initialization of .db (which i assume is dat...

import responses
import requests

@responses.activate
def test_simple():
responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
json={'error': 'not found'}, status=404)

resp = requests.get('http://twitter.com/api/1/foobar')

assert resp.json() == {"error": "not found"}

assert len(responses.calls) == 1
assert responses.calls[0].request.url == 'http://twitter.com/api/1/foobar'
assert responses.calls[0].response.text == '{"error": "not found"}
plucky geode
#

Anyone have experiiience adding a javascript testiinig framework (Like jest) to a django application?

proper wind
#

Hey can someone send a ddos attack to this ip? I'm creating a VPN service, and I want it to stand straight attacks. This is just a test ip it doesn't belong to anyone, it's sole purpose is to act as a test, I'd like a hard attack, preferably for a day. The Ip is 192.168.8.243

pearl cliff
proper wind
#

It's not meant to hide my ip, it's meant to withstand attacks like cloudflare.

pearl cliff
#

192.168.8.243 is reserved for private IP addresses, such as on your local home network

#

if i run ping 192.168.8.243 i get a request timeout, because there is nothing on my local network with the IP address 192.168.8.243

#

ARIN specifically designates the 192.168.0.0/16 range (192.168.0.0 through 192.168.255.255) for private use, and those addresses will generally not be routable from the internet

proper wind
#

I see. So you wouldn't be able to send packets.

pearl cliff
#

indeed

proper wind
#

That ruins the test:/

pearl cliff
#

you will need to expose it through your router. then if you set up a remote server to dos yourself, you'll probably just end up dosing your home router.

plucky geode
#

anyone available to help me with docker setup and understanding?

#

I am trying to setup jest.js to test the frontend of a django app

proper wind
pearl cliff
#

doesn't seem like it's what you want to test

errant crane
#

Anybody can help me

limber harness
#

How would I handle exceptions from unit testing?

    raise self.failureException```
proper wind
fresh blade
limber harness
#

Thanks guys

limber harness
fresh blade
limber harness
#

Thanks for this! I rather save time

proper wind
#

I am writing integration tests that have multiple pytest fixtures that use the same limited resources. How do I adjust the scoping such that these fixtures can all be run in the same module/session without the resources being depleted?

I want to control the reservation of these resources at the session level though but if all the fixtures have a session scope they end up reserving the resource for the entire session and tests end up not being able to run

#

Also if I run the fixtures at the class scope the tests end up taking way too long because of the time it takes to reverse and configure the resources

sly heron
#

Hello all
I am starting to write unit tests for my project. I would like to have unit tests to run without any external system including database. So one way to mock the database calls itself. So having few questions related to it.

  1. Is it good idea to mock the db calls or should spawn the db system at the time of tests?
  2. If mocking is fine, then are there any patterns to mock such calls? If anyone can suggest any opensource project where I can look for the similar tests writing.
maiden pawn
#

in fact, django framework does it automatically for you. During tests it makes empty migrated database for each test.

#

Possibly it does testing framework perhaps, not the Django? not sure which part of my app does that.

#

Additional advice: if you are going to use postgresql in production, it would be better to run your tests in postgresql (not in sqlite) (as a last resort in sqlite will do too, at least it is better than mocking).

smoky grail
#

can anyone help me with python web scrapy unittesting
im kinda stuck in testing the parse part and dont know how to start or do

dim panther
#

I want to learn testing .... it appears i could use pytest, unittest, nose
is there a preference amongst these ?

fresh blade
dim panther
#

Thank you @fresh blade

river pilot
#

nose has been unmaintained for more than five years

river pilot
potent quest
#

furthermore, 10 years+ of development and only 1,006 commits?!

river pilot
potent quest
#

I've been working on something for 2 months and have already 300+ commits

potent quest
river pilot
potent quest
#

or update it to nose2 πŸ˜›

#

seems to be maintained

pearl cliff
#

nose references seem to be all over the python ecosystem docs

proper wind
#

I don't understand what "change dir before test and use per-virtualenv tempdir" means lirikHUH

#

Also, is there a way to run tox from code rather than command line so i can hook into vsc debugger?

#

oh, it's literally this rooDerpy ```py
import tox
tox.cmdline()

jaunty hearth
ember maple
torn solstice
#

hi, anyone works on postman here for testing?

#

I have a doubt, how can I set default query parameters to a collection which applies to all the requests in that collection?

pearl cliff
proper wind
#

Is there a way to have pytest show the number of tests per file rather than just dots? like the (9) here that I've inserted ```
tests\run_many\languages_json\test_languages_json.py ......... (9)

#

I don't want to use verbose mode since that's too verbose πŸ˜…

rose oyster
pearl cliff
fiery arrow
#

Fork pytest hyperlemon

#

Increment a global variable in each test brainmon

cobalt ore
#

How sensible / silly is it to have different tests run on different systems? I have some tooling which uses google things, which aren't tested because there's application credentials and stuff required to run them (and I'd rather not test googles stuff but just trust it works - these are wrappers around things like bigquery / translation and whatever).

The other day someone refactored something, and broke some of the tooling, so I was considering having a subset of the tests run locally (where the application keys are set), and the rest run on CI and local πŸ€”

i'm not sure if this is a "done thing" or not though

pearl cliff
#

both pytest and unittest have features that let you conditionally skip tests

#

it's not the worst thing ever, but it might lead to tests that you have less confidence in

fierce flare
#

List of SeleniumBase features completed/updated over the past year: https://github.com/seleniumbase/SeleniumBase

  • Dashboard
  • Dialog Boxes
  • Product Tours
  • Chart Maker
  • Presenter
  • Locales
  • Visual Testing
  • Traffic Generator
  • Universal Translator
  • ShadowDOM Piercer
  • SOCKS 4/5 Proxy Setter
  • ChromeDriver Auto-Upgrader
GitHub

βœ… πŸ“Š Automate Web Testing with Selenium, Python, and pytest. πŸš€ - GitHub - seleniumbase/SeleniumBase: βœ… πŸ“Š Automate Web Testing with Selenium, Python, and pytest. πŸš€

limber harness
#

Hi unit test peoples. How would I go about unit testing a script that makes REST API calls using requests? Would I create a mock response and test that?

kind meadow
pearl cliff
#

yes, you will need to create some fake data to "respond" to your requests

maiden pawn
bitter wadiBOT
#

:incoming_envelope: :ok_hand: applied mute to @normal meadow until <t:1630041911:f> (9 minutes and 58 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).

drowsy hawk
#

i'm working on a pytest fixture which ensures that a test does not produce any garbage or explicitly run gc, but having some trouble testing that it works as intended; when i use a strict xfail marker on a test that produces garbage and correctly causes an error, it still detects xpass and fails, there doesn't seem to be any "xerror" marker which is what i would need. maybe producing an error from the fixture isn't what i should be doing?

#
import gc
import pytest


@pytest.fixture
def nogarbage():
    did_gc = [False]
    def fail_gc(phase, info):
        did_gc[0] = True

    was_enabled = gc.isenabled()
    gc.disable()
    gc.freeze()
    try:
        gc.callbacks.append(fail_gc)
        yield
        gc.callbacks.remove(fail_gc)
        assert not did_gc[0], "Garbage collected during test"
        for gen in range(3):
            assert gc.collect(gen) == 0, f"Garbage collected after test (gen {gen})"
    finally:
        gc.unfreeze()
        if was_enabled:
            gc.enable()


@pytest.mark.xfail(strict=True)
def test_circular(nogarbage):
    l1 = []
    l2 = [l1]
    l1.append(l2)
rose oyster
limber harness
#

Thanks everyone. Is there any examples of that out there?

rose oyster
#

I would think on the design of the tests. Test, if the view receives the request correctly - mock request. Test, if the data is serialised correctly - mock the data. Test if it returns the correct response - mock response.

pearl cliff
#

i'm interested in this tooling for testing the test fixtures

#

i never had a good solution for that

drowsy hawk
#

pytester is the solution, thing is raises and xfail are made to deal with test failures, not fixture errors

#

the pytest plugin cookiecutter actually sets this up for you

#
def test_nogarbage_fixture(testdir):
    testdir.makepyfile("""
        import gc

        def test_fail(nogarbage):
            assert False

        def test_pass(nogarbage):
            pass

        def test_circular(nogarbage):
            l1 = []
            l2 = [l1]
            l1.append(l2)

        def test_collect(nogarbage):
            gc.collect()
    """)

    result = testdir.runpytest(
        '-v'
    )

    result.stdout.fnmatch_lines([
        '*::test_fail FAIL*',
        '*::test_pass PASS*',
        '*::test_circular ERROR*',
        '*::test_collect ERROR*',
    ])

    assert result.ret != 0
pearl cliff
#

neat

slate brook
#

pytest and unittest find the tests by filename, right? What are the most common naming conventions? Anything with test in it?

maiden pawn
slate brook
#

Cool, I'm doing a mixed Python/C++ project and just want to make sure I'm using consistent naming schemes. In C++ some people prefer some_file.test.cpp for example.

maiden pawn
#

Python convention for test searching can be adjusted

#

Check if u can adjust c++

#

If not, then better to follow c++ convention

slate brook
#

yeah, all the C++ ones are just listed explicitly in a config file, they could be called anything in principle.

maiden pawn
#

Well. U can follow convention of both languages then

#

It does not look like conflicting

#

It will make less confused python devs, if others will participate

slate brook
#

less confusion is a plus

magic timber
#

Does ubuntu have a disk wipeing program buiit in

maiden pawn
magic timber
#

Ok thanks

#

That helps so munch

fickle gazelle
#

Hi

#

I have done functionnal tests on a flask full api using pytest

#

Firstly I want to know if the testing must be done when the app is running or not (I think so)

#

Because I have an issue when testing a given route that is calling another api (inside my own app)

#

The tests in the detailed log said that it is not reachable (the other api nested)

#

When I run the app the tests works surely

#

How to fix this issue

#

plz

maiden pawn
fickle gazelle
#

with the app closed?

#

Thxx

#

I want to do a prebuild tests

#

so the app should be closed, no? @maiden pawn

maiden pawn
fickle gazelle
#

I didn't find any thing 😦

fickle gazelle
#

ok thxx I will see @maiden pawn

#

@maiden pawn plz can you send me the name of the section in detail or a screen or a part of the paragraph

#

I didn't find it

fickle gazelle
#

Please @all any help

haughty summit
#

does unittest support async tests?

maiden pawn
#

I used async plugin support for pytest, it worked smoothly

kind meadow
#

Yes it does out of the box since 3.8 or 3.7, something around there

#

You have to inherit from a special testcase subclass for async tests

maiden pawn
#

cool.

kind meadow
#

Thanks for finding that I couldn't remember the name and I'm on mobile

fiery basalt
#

Hi, How to design a test that can roll one parameter out?
I've designed a model that some of the column are nullable and some are not.
Is there any source that I can follow for this situation?
Thanks!

#

For example: suppose duration is nullable and others are not, then I might need two test cases to confirm that either missing plan_id or missing available_before will raise the error.
The dumb way I've thought of is create two Plans for the test, but any smart way to deal with it?

def test_add_param_deficient_plan(self):
        try:
            p = Plans(
                plan_id = "standard-month-1",
                available_before = dt.strptime("2021-08-20", "%Y-%m-%d"),
                duration = 1
            )
            db.session.add(p)
            db.session.commit()
        except:
            db.session.rollback()
        self.assertRaises(exc.IntegrityError)
haughty summit
#

lol thats too verbose

pearl cliff
#

i assume it's "isolated" because it uses its own separate event loop

#

i've been using my own decorator that wraps test cases in asyncio.run

#

time to switch

plush vale
#

ye pytest-asyncio takes the same approach of running each test in a new event loop, which makes sense (by default, you can redefine the event_loop fixture)

#

to allow testing using different loop implementations, and to ensure resources dont leak between tests

#

though I was dealing with the problem recently that as a result you cannot share async resources like db connections between tests because then they get bound to the wrong loop

#

maybe you shouldn't do that anyway

#

but there's also the consequence that you cannot have an async fixture scoped above function (eg to run migrations in session scope)

#

i ended up solving it by just having a sync fixture and doing asyncio.run inside, couldnt think of a better approach, im a noob 😐

pearl cliff
#

event loop scoping is annoying

#

the loop "closing" and not being restartable is annoying too, not sure if that's a technical limitation or just a design oversight

open venture
#

Hey people
How do you deal with large files in github?
Like i need to have a large bianary (linux kernel) in my github CI
The CI will run some tests using that binary
but since the kernel is like >500Mb , git wont work
git LFS may work
but is it the best solution?
has anyone come across this problem?

deft bronze
#
    def create_xyz_table(self, table_name: str, source_table_name: str) -> None:
        logger.info(f"[+] Creating table [{table_name}]")

        self.mysql_client.run_mysql_query(f"CREATE TABLE `{table_name}` LIKE `{source_table_name}`")

        logger.info(f"Table [{table_name}] created")
#

Hi, I am writing unit tests for this method.

#

I already have a unit test that asserts that run_mysql_query has been called.

#

I would maybe like to have once that verifies the query that is passed to run_mysql_query. My only worry is that there is then code duplication... 1 string will be in my unit test, and another string will be in the function.

kind meadow
# open venture Hey people How do you deal with large files in github? Like i need to have a la...

Yes, I am facing that problem too, where it isn't feasible to generate the test data so it must be stored. The problem with checking in a binary on git is that anyone who clones it will clone this large binary too, even if they may not be intending to run tests. It's even worse if you plan on updating the binary since that will end up bloating the size of git's history.

You could host the binary on a server and have CI download it. Downside is that the server could go down in the future and there won't be a way for people to get this test data.

One idea given to me was to have some smoke tests that don't rely on large binaries, and then have the CI run the full tests by downloading the binary from another server.

open venture
#

@kind meadow I see.

#

What i;m thinking is to build the binary in the CI intially and then cache it

#

So it stays in the CI cache.

maiden pawn
#

special repository "for big files"

open venture
#

github has a feature called LFS

#

I'm planning to use that if I can;t come up with any better indeas

maiden pawn
#

oh, that's a neat choice

open venture
#

Thanks

#

Actually im kinda new so i thought people might have better solution to this

maiden pawn
#

I just have download on a fly instructions

#

building dockerfile with downloading stuff from where it is

open venture
#

But for it each CI run will take ages

#

First download the linux kernel, then build it

maiden pawn
#

plus you could use its caching/artifacts (or how it is called there)

open venture
#

lol

maiden pawn
#

which would persist it between CI runs

#

to speed it up

open venture
#

i'm in college

open venture
#

that after running it once we cache it, so nect time CI doesnt take time

maiden pawn
#

in theory

#

we could have all those dependencies

#

being available for download

#

from our running server

#

while having them stored in separate repository again

#

this will make sure that we will be able having those dependencies

#

self raised and downloaded from our own server, being sure that they will not dissapear

#

but that's a bit too crazy solution

#

for small things probably not needed

open venture
#

indeed its a crazy one, for a two man project

#

maybe bigtime projects do this

#

btw, Thanks for ideas

pearl cliff
#

@open venture LFS is a fine option. another option is to use DVC (which is mostly used for data science but could definitely be used here) and then store the binary in a separate location that you can pull from in your CI

#

yet another option is to just push the binary to some file store you control, like a basic ftp server on a cheap vps instance

open venture
#

I see thanks @pearl cliff

autumn shore
#

Hi, can someone help me with my project idea is to test a program i tried to make ( the program is to put in ingredients we have and it shows the available recipe for us), it just an idea not to fully make the program.

maiden pawn
# autumn shore Hi, can someone help me with my project idea is to test a program i tried to mak...
Manning Publications

Unit Testing Principles, Patterns and Practices shows you how to refine your existing unit tests by implementing modern best practices. You’ll learn to spot which tests are performing, which need refactoring, and which need to be deleted entirely! Upgrade your testing suite with new testing styles, good patterns, and reliable automated testing.

#

it is great to learn testing philosophy

autumn shore
#

ohh

arctic oak
#

Can anyone here help walk me through the Mock() object and the patch() decorator?

#

I read a few articles on it and a few things are still unclear

#
requests = Mock()

def get_holidays():
    r = requests.get('http://localhost/api/holidays')
    if r.status_code == 200:
        return r.json()
    return None

class TestCalendar(unittest.TestCase):
    def test_get_holidays_timeout(self):
        # Test a connection timeout
        requests.get.side_effect = Timeout
        with self.assertRaises(Timeout):
            get_holidays()

if __name__ == '__main__':
    unittest.main()
#

For example in this snippet, how do I know get_holidays() is handling the Timeout exception?

#

Timeout gets raised first, then why would I call get_holidays() afterwards?

#

Shouldn't the Timeout happen inside the get_holidays()?

proper wind
#

I think the with self.assertRaises(Timeout): begins a context manager that is setup to cach the exception specified for get_holidays. Then get_holidays is run. If there is an exception it will be returned to the self.assertRaises call. You can also give the return object a name and inspect it after: with self.assertRaises(SomeException) as cm:

#

I don't know why requests is being set to Mock there though. Typically you would use a decorator over the test to patch the actual requests library and then set the mocked requests to have the side_effect.

proper wind
#
import unittest
from unittest.mock import Mock, patch

import requests
from requests.exceptions import Timeout


def get_holidays():
    r = requests.get("http://localhost/api/holidays")
    if r.status_code == 200:
        return r.json()
    return None


class TestCalendar(unittest.TestCase):
    @patch("requests.get")
    def test_get_holidays_timeout(self, mocked_requests_get):
        # Test a connection timeout
        mocked_requests_get.side_effect = Timeout
        with self.assertRaises(Timeout) as exc:
            get_holidays()
        self.assertEqual(type(exc.exception), Timeout)
        mocked_requests_get.assert_called_once_with(
            "http://localhost/api/holidays"
        )


if __name__ == "__main__":
    unittest.main()
open venture
#

Hey people, how to add this checks box to a github PR using github actions?

#

Like is adding on: [push, pull_request] this to the .yml is enought?

plush vale
#

I think you need to set branch protection in the repo settings

#

this explains it

#

you're interested in point 7

#

but the others may be interesting to you too

arctic oak
proper wind
#

The patch decorator is wrapping the function. It's patching the requests.get and passing in the mock of that as an argument to the function for you to use. You can add multiple ones on top of each other as well and they would get added in as more arguments. It gets evaluated bottom up.

#
@patch.object(SomeClass, 'class_method')
@patch.object(SomeClass, 'static_method')
def test(mock1, mock2):

^ That's from the docs. mock1 would be static_method mock and mock2 is class_method mock. @arctic oak

open venture
bitter wadiBOT
#

:incoming_envelope: :ok_hand: applied mute to @peak basin until <t:1631026729:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).

stuck plume
#

guys need help in testing Django signals
I have implemented the user login activity
so when the user logs in It fires a signal 'user_logged_in' which creates an entry in a table

I need help in testing this

deft bronze
#
@patch("datetime.datetime")
@pytest.mark.parametrize(
    "input, expectation",
    [
        (
            TestDate(2020, 5),
            does_not_raise(),
        ),
    ],
)
def test_months_to_archive_year_input_valid(mock_datetime, input, expectation, app_manager):
    mock_datetime.utcnow.return_value.year = 2021

    with expectation:
        result = list(app_manager.get_months_to_archive(input.month, input.year))

        assert len(result) == 5
#
app_manager.py
...
while start_date <= formatted_current:
    if start_date.month == current.month and start_date.year == current.year:
        break

    yield start_date

    start_date = start_date + monthdelta(1)
#

My unit test is mocking datetime.datetime, and this causes problems when the unit test reaches the portion of code that is comparing datetime objects with "<=" because: TypeError: '<=' not supported between instances of 'MagicMock' and 'MagicMock'

#

Anyone knows how to fix this?

river pilot
#

@deft bronze I like freezegun for faking time-based code.

fresh blaze
#

Hi, I have a function that takes three arguments like this:

def func(a, b, c):
  return a + b + c

or whatever have you.

I also have a separate tests folder where I would like to test the func.

  • is @python.fixture a good option for this?
    I have been trying with this approach and added the decorator to the func definition in the "code" file, while wanting to test it in another. What is returned to me is fixture 'a' not found. What am I doing wrong? πŸ™‚
pearl cliff
#

(note: hypothesis apparently doesn't play well with @patch as a decorator)

#

i wonder if patch('datetime.datetime.utcnow') works? probably not

#
from contextlib import nullcontext
from datetime import datetime
import pytest
import app_manager

@pytest.mark.parametrize(
    ('input_then', 'input_now', 'expected_len'),
    [
        (datetime(2020, 5), datetime(2021, 1), 5),
    ],
)
def test_months_to_archive_year_input_valid(input_then, input_now, expected_len, app_manager):
    with patch('datetime.datetime') as mock_datetime:
        mock_datetime.utcnow.return_value = input_now
        result = list(app_manager.get_months_to_archive(input.month, input.year))
        assert len(result) == expected_len

@pytest.mark.parametrize(
    ('input_then', 'input_now', 'expected_err'),
    [
        (datetime(2020, 5), datetime(1983, 7), (app_manager.SomeException,)),
    ],
)
def test_months_to_archive_year_input_invalid(input_then, input_now, expected_err, app_manager):
    with patch('datetime.datetime') as mock_datetime:
        mock_datetime.utcnow.return_value = input_now
        with pytest.raises(*expected_err):
            list(app_manager.get_months_to_archive(input.month, input.year))
pearl cliff
fresh blaze
#

Ah - gotcha! so it's usually on the testing side as a "fixture" (see what I did there? πŸ˜‰ )for tests to reuse the same data for multiple tests?

pearl cliff
pearl cliff
fresh blaze
#

@pearl cliff So I would never want to use this decorator anywhere outside the tests file, like I wouldn't want to use it on the "code" side? Or if a resource is defined in code, I would use it there? Like with your example about the db connection, if creds are set up on the "code" side I could potentially use it as a fixture for the tests on the "testing" side?

#

I read this and I'm not sure I am making sense πŸ˜‰

pearl cliff
#

you wouldn't use it on "real code", but you could write a fixture that uses real code in order to acquire the resource

#
import pytest
from my_very_serious_app import get_database_from_env

@pytest.fixture
def database_connection():
    return get_database_from_env

def test_something(database_connection):
    ...
fresh blaze
#

Perfect - thanks

pearl cliff
#

pytest has a ridiculous number of features btw

#

i recommend reading that fixtures doc page in small pieces

fresh blaze
#

Yeah I started reading this...and then I stopped

#

I have one more question on good practice

#

Let's say I have a .csv file as a resource, where I have a bunch of tweets. It's usually read in by "code" and then processed to fit a particular task, say NLP. If I wanted to test the cleaning function, would I create test strings using some custom-prepared ones as a fixture? or would I be trying to use the initially loaded file as a resource in any fashion?

pearl cliff
#

do whatever you need to do in order to test that the function "works", where "works" means something like "produces the expected outputs on a controlled list of inputs" or "maintains certain invariant properties on randomized inputs"

fresh blaze
#

right - much appreciated - thanks!

ember maple
#

hypothesis helps for the randomization

pearl cliff
#

+1, nowadays i even use hypothesis to generate entire databases worth of data, write the data to the database, and then make assertions about queries against that data

#

although i really should start looking into ways to control the number of test examples that get generated, i'm concerned i might destroy the ssd on my work computer if i do that too much...

plush vale
#

i found myself working on a project where extensive testing is crucial and generating the data has been a bit of a pain point

#

but since i'm still kinda lost in the domain i scheduled a meet with someone senior in the area so hopefully they'll set me on the right path πŸ™

#

it seems to me that proper testing is the hardest problem i keep encountering

#

for the past couple of days i've been working on solving the problem of paginating huge amounts of data and providing it to the frontend on-demand, but the data is very alive and volatile

#

and keeps changing in basically real time

#

the solution itself aside, i don't really have a good idea of how to approach testing this

#

i'll not only need to generate a lot of data, but i'll have to be changing it as the test is running and somehow verify that the paginating algorithm recovers when certain events happen

pearl cliff
pearl cliff
#

e.g. if your code is

def fetch_paginated(resource):
    while (page := resource.fetch()) is not None:
        yield from page

then you'd use some kind of text fixture that dynamically produces new data upon calling fetch

#

in that world you're no longer able to hard-code inputs and outputs, you basically have to specify your test as a collection of invariants to be asserted

plush vale
#

yeah, I see what you're saying, roughly

#

though in a real world scenario it gets complicated, since you can have multiple clients requesting different chunks of the data with various filter and sort criteria

#

but I guess that can still be simulated if you design everything well enough

#

the reason why I'm thinking in the direction of using something like hypotheses is because it seems like there's an insurmountable amount of variables affecting the whole system

#

and I keep coming back to the realization that if you're unaware that your code breaks in a specific situation, you probably won't write a test that triggers it

maiden pawn
#
def sum(a: int, b:int):
    """
    >>> sum(2,3)
    5

    >>> sum(6,8)
    14

    """
    return a+b

huh

pytest --doctest-modules

this will catch doctests in addition. cool.

#

it will make a fine addition, to have tests and self documentation at the same time

#

oh yeah, better just adding to ini file for auto flag inclusion

# content of pytest.ini
[pytest]
addopts = --doctest-modules
static grove
#
@pytest.mark.parametrize(
    'func', [
        two_sum,
        two_sum_reverse,
        with_buffer
    ]
)
@pytest.mark.parametrize(
    'nums, target, indexes', [
        ([2, 7, 11, 15], 9, [0, 1]),
        ([3, 2, 4], 6, [1, 2]),
        ([3, 3], 6, [0, 1]),
        ([-1, 2, -3, -5, 6, -7], -10, [2, 5]),
        ([0, 0], 0, [0, 1])
    ]
)
def test(func, nums, target, indexes):
    assert func(nums, target) == indexes
#

the tests with the last 2 functions fail because they return None

#

and it's the same if I change the order of func

#

so it seems like the other parameters nums, target, indexes are getting exhausted after the first function

#

they're actually receiving nums = [], target = 0

#

why?

abstract sandal
#

-=[Β΄/~

maiden pawn
# static grove ```py @pytest.mark.parametrize( 'func', [ two_sum, two_sum_r...

as much as of I could check within provided code.

import pytest


def two_sum(*args, **kwargs):
    pass


def two_sum_reverse(*args, **kwargs):
    pass


def with_buffer(*args, **kwargs):
    pass


@pytest.mark.parametrize("func", [two_sum, two_sum_reverse, with_buffer])
@pytest.mark.parametrize(
    "nums, target, indexes",
    [
        ((2, 7, 11, 15), 9, (0, 1)),
        ((3, 2, 4), 6, (1, 2)),
        ((3, 3), 6, (0, 1)),
        ((-1, 2, -3, -5, 6, -7), -10, (2, 5)),
        ((0, 0), 0, (0, 1)),
    ],
)
def test(func, nums, target, indexes):
    assert isinstance(nums, tuple) and len(nums) > 0
    assert isinstance(target, int)
    assert isinstance(indexes, tuple) and len(indexes) > 0
    func(nums, target)
#

there are no empty lists

#

possibly your functions have side effects

#

as a choice we can just use immutable list

#
import pytest


def two_sum(*args, **kwargs):
    pass


def two_sum_reverse(*args, **kwargs):
    pass


def with_buffer(*args, **kwargs):
    pass


@pytest.mark.parametrize("func", [two_sum, two_sum_reverse, with_buffer])
@pytest.mark.parametrize(
    "nums, target, indexes",
    [
        ((2, 7, 11, 15), 9, (0, 1)),
        ((3, 2, 4), 6, (1, 2)),
        ((3, 3), 6, (0, 1)),
        ((-1, 2, -3, -5, 6, -7), -10, (2, 5)),
        ((0, 0), 0, (0, 1)),
    ],
)
def test(func, nums, target, indexes):
    assert isinstance(nums, tuple) and len(nums) > 0
    assert isinstance(target, int)
    assert isinstance(indexes, tuple) and len(indexes) > 0
    func(nums, target)
pearl cliff
#

@static grove ☝️

#

e.g. if your test function pop's or del's elements

maiden pawn
pearl cliff
#

oops

#

instead making the list immutable, you can also make a copy of the list in the test function

#

or change the parameterized mark to a fixture that generates new data on every call

maiden pawn
#

I think using immutable data for unit tests input is just best practice

#

well, and for data in general inputed to functions

pearl cliff
#

i wish we had frozenlist, frozendict, etc.

#

tuples are semantically not lists and using them as lists bothers me!

maiden pawn
#

i remember there is frozendict

pearl cliff
#

unless they added it later?

maiden pawn
#

a second, I'll find it. it was in one of my books

pearl cliff
#

there is a pypi package for it

#

but not stdlib

maiden pawn
bitter wadiBOT
#

@maiden pawn :x: Your eval job has completed with return code 1.

001 | {'123': 1, '456': 2}
002 | Traceback (most recent call last):
003 |   File "<string>", line 7, in <module>
004 | TypeError: 'mappingproxy' object does not support item assignment
pearl cliff
#

oh that's an interesting way to do it

#

!e ```python
from types import MappingProxyType
dicty = {"123": 1, "456": 2}
frozen_dict = MappingProxyType(dicty)
del dicty
print(frozen_dict['123'])
frozen_dict["123"] = 3

bitter wadiBOT
#

@pearl cliff :x: Your eval job has completed with return code 1.

001 | 1
002 | Traceback (most recent call last):
003 |   File "<string>", line 6, in <module>
004 | TypeError: 'mappingproxy' object does not support item assignment
maiden pawn
# pearl cliff oh that's an interesting way to do it

https://stackoverflow.com/questions/41795116/difference-between-mappingproxytype-and-pep-416-frozendict/41795417

TL;DR
MappingProxyType is a read only proxy for mapping (e.g. dict) objects.
frozendict is an immutable dict

#

so, to insure its immutableness, better creating always as frozen_dict = MappingProxyType({"123": 1, "456": 2})

#

so there would be no other links to this dictionary left

pearl cliff
#

right, you can discard the binding to the original data and then pass around the mapping proxy

#

that's neat

#

probably slower for lookups than a plain dict though

#

i imagine the "right" way to make a frozendict would be to do it at the C level and just disable __setitem__

#

too bad there's no SequenceProxyType

#

could probably make one with sufficient drudgery

maiden pawn
#

if it works like a sequence, if it is immutable, then it is probably SequenceProxyType

#

so lets just use tuple for this ;b duck typing in a nutshell

pearl cliff
#

blech

maiden pawn
#

or you are worried that it implements too many additional methods?

#

which SequenceProxyType should not have?

pearl cliff
#

i'm worried because it's semantically the wrong thing and i don't want to be a hypocrite because i always emphasize using semantically correct data types πŸ˜›

bitter wadiBOT
#

Lib/types.py line 15

MappingProxyType = type(type.__dict__)```
pearl cliff
#

πŸ€·β€β™‚οΈ using the minimal Sequence implementation as per https://docs.python.org/3/library/collections.abc.html

from collections.abc import Sequence
from typing import TypeVar

TypeVar = TypeVar('A')

class SequenceProxy(Sequence[A]):
    def __init__(self, mapped: Sequence[A]) -> None:
        self._mapped = mapped

    def __getitem__(self, idx: int) -> A:
        return self._mapped[idx]

    def __len__(self) -> int:
        return len(self._mapped)
static grove
#

thanks

proper wind
#

rg

modest harbor
#

Hi all,

I've been using Python on and off for 10 years, and I just rediscovered a problem that has always irked me.

I made a booboo, removing __init__.py from my tests directory, so when I run python3 -m unittest discover it doesn't find any tests.

python3 -m unittest discover

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

The problem is this passes my automated build process (basically a Makefile) because the return code of that command is still 0.

So my question is, does anybody know of an easy way to make unittest fail if no tests were run? I could check the output for "Ran 0 tests..." but that seems a little hacky.

Limitations:

  • I'm using Python 3.9.
  • I don't like dependencies unless really necessary, so I'm trying to avoid using pytest, nose or similar, but if they solve this problem then I would consider it.

Thanks, really appreciate everybody in the Python community.

modest harbor
#

Actually, I solved my own problem: My favorite solution is to use coverage.py with it's --fail-under option which will fail if no source code is executed.

maiden pawn
#

It is python server, so no

#

Try asking there

#

I remember they have a place for homeless languages

#

The channel is named so

bitter wadiBOT
#

Hey @proper wind!

It looks like you tried to attach file type(s) that we do not allow (.rar). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a.

Feel free to ask in #community-meta if you think this is a mistake.

formal sonnet
#

anyone ever have issues with pytest-asyncio not applying even though its installed?

wary pier
#

i.e., collaborating with Python..

bitter wadiBOT
keen estuary
#

uhhh

#

hello

#

-eval

print("jr")
bitter wadiBOT
#

@keen estuary :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     /viewauction https://paste.pythondiscord.com/ezuhicepoq.py
003 |     ^
004 | SyntaxError: invalid syntax
keen estuary
#

wait

bitter wadiBOT
#

@keen estuary :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     https://paste.pythondiscord.com/ezuhicepoq.py
003 |           ^
004 | SyntaxError: invalid syntax
pearl cliff
#

And no it won't let you run your bot inside the bot

keen estuary
forest minnow
#

can anyone help me writing a unittest with pytest for an argparse argument to assert that it is indeed required?

pearl cliff
pearl cliff
#

So you can test arbitrary combinations of cli args that way

formal sonnet
#

Anyone have good examples of testing with unittest.mock and async methods?

pearl cliff
formal sonnet
# pearl cliff can you be more specific about what you're trying to test? i do this at work som...

I'm testing some of my bot commands for discord.py, creating mocks, like ctx mock. Could you give me some pointers in using mock and testing my code?

phase = SignUpPhase()
ctx_mock = Mock()

@pytest.mark.asyncio
async def test_create_cateogory():
    category = 'category'
    future = Future()
    future.set_result(category)

    ctx_mock.guild.create_category.return_value = future 

    assert await phase._create_category(ctx_mock, category) == category

    ctx_mock.guild.create_category.assert_called()
    ctx_mock.guild.create_category.assert_called_with(category)
potent quest
#

what in the world....

#

this is going to take a few days to write, since there is so much about pytest that I can learn to make this so nice

potent quest
pearl cliff
#

maybe you want ```python
ctx_mock.guild.create_category = AsyncMock()

instead?
#
ctx_mock.guild.create_category = AsyncMock()
ctx_mock.guild.create_category.return_value = category
ebon nacelle
#

General question, how can I improve readability of my integration tests on this open-source project I'm a part of:
https://github.com/Energy-Track-and-Trace/ett-meteringpoints/blob/test/meteringpoints_setup/tests/meteringpoints_consumer/test_handlers.py (Updated link)

Currently each test are very long, and not like something you would think is very maintainable. My biggest struggle is how to test a endpoint that returns a list of objects, like on line 580.

GitHub

MeteringPoints domain. Contribute to Energy-Track-and-Trace/ett-meteringpoints development by creating an account on GitHub.

potent quest
ebon nacelle
pearl cliff
#

Sometimes tests are just huge

#

At work i probably write at least as many test LoC as prod

potent quest
#

jeez

#

I have about 1k lines of code I've written in the past week

#

and 2k of those lines are not tested

pearl cliff
#

That section at line 580 is totally reasonable @ebon nacelle

#

Loop over something, construct an expected outcome, assert equality

potent quest
#

^

pearl cliff
#

That triple quoted string will go out of date quickly

#

I'd dispense with it unless you have a tool to keep it automatically in sync with the code

potent quest
#

the docstring?

pearl cliff
#

It's not a docstring if it's sitting there at the top level after the imports πŸ˜‰

potent quest
#

oh that one

#

why does it use ''' and not """

pearl cliff
#

I would at least move those items to the individual docstrings of the test classes/functions

potent quest
#

^

#

you can write plugins for pytest which do actually automatically update docstrings

potent quest
#

writing them is so satisfying

potent quest
#

just make sure you commit often while writing them in case one of them messes up and edits the wrong thing to the wrong file πŸ˜›

ebon nacelle
#

But can't we agree that the test at 580 isn't that readable as well as maintainable? This project is still in it's early stages so I'd expect lots of stuff to change, therefor the tests open for changes as well

pearl cliff
#

No I thought it was perfectly readable

potent quest
# pearl cliff Got an example?

not super much, but its defintely possible to collect all tests with pytest and get their metadata
There's a library for automatically exporting a docfile of all pytest files, but its not the best.

#

!pypi pytest-docs

bitter wadiBOT
pearl cliff
#

@ebon nacelle it's not flexible if your design is actively changing and WIP

#

In that case then yes, you don't necessarily want to test properties that you aren't comfortable testing

ebon nacelle
#

About the "docstring" you are right, that's not optimal. The idea were to have some kind of system to see what gets tested where. As you might have noticed, the tests assert multiple things, so it's an attempt to get and overview

potent quest
# bitter wadi

@pearl cliff that's an example of automatic test docs, but I think it would be more useful to read the source of that plugin and migrate it to be a new plugin πŸ˜›

pearl cliff
#

That or just accept that you will have to change your tests frequently. That also isn't a bad thing necessarily

potent quest
#

yeah

#

the bad thing is when you fully refactor your code including public apis and the tests still run perfectly cri

#

will neither confirm nor deny that it was both a nice feeling and bad feeling if that happened to me last week hypothetically

ebon nacelle
#

sounds pretty cool with the pytest-docs gotta look into that πŸ˜›

However I still disagree with the tests being fine, I'm not satisfied with how "confusing" they are as of now. Gotta figure out what to do lol

potent quest
ebon nacelle
#

You mean in pytest-docs?

unreal plank
spiral arch
#

A function will always return something. A function without an explicit return will return None.

#

@floral grotto

#

!e py def func(): pass print(func() is None)

bitter wadiBOT
#

@spiral arch :white_check_mark: Your eval job has completed with return code 0.

True
bitter wadiBOT
#

:incoming_envelope: :ok_hand: applied mute to @woeful whale until <t:1632482670:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).

maiden pawn
#

you can test anything that can be checked for True!
!e

def test_your_things():
    # arrange
    first_number = 6
    second_number = 2
    string_with_stuff = "stuff"

    # act
    is_stuff_in_stuff = "stuff" in string_with_stuff
    calculated_sum = first_number + second_number

    # assert
    assert is_stuff_in_stuff
    assert calculated_sum == 8

test()
hexed sierra
#

!e

def solve(nums, div):
    for i in nums:
        j = i % div
        x = i + j
        nums.insert(i, x)
    return nums


solve([2, 7, 5, 9, 100, 34, 32, 0], 3)
bitter wadiBOT
#

@hexed sierra :warning: Your eval job timed out or ran out of memory.

[No output]
hexed sierra
#

i made a simple program that no one can run

dry walrus
#

!e

def solve(nums, div):
    for i in nums:
        result = []
        j = i % div
        x = i + j
        result.insert(i, x)
    return result


solve([2, 7, 5, 9, 100, 34, 32, 0], 3)
bitter wadiBOT
#

@dry walrus :warning: Your eval job has completed with return code 0.

[No output]
dry walrus
#

!e

def solve(nums, div):
    result = []
    for i in nums:
        j = i % div
        x = i + j
        result.insert(i, x)
    print(result)
    return result


solve([2, 7, 5, 9, 100, 34, 32, 0], 3)
bitter wadiBOT
#

@dry walrus :white_check_mark: Your eval job has completed with return code 0.

[0, 4, 8, 7, 9, 101, 35, 34]
pearl cliff
#

returning True has nothing to do with whether a function is testable

real aurora
#

a test is basically only a function that runs the function that is to be tested and then compares what the function returns (or something else, it can be anything really) has the expected value(s)

potent quest
#

In that case, you'd want to test that what was printed was what was expected to print.

fading ermine
#

!e print(1+2)

bitter wadiBOT
#

@fading ermine :white_check_mark: Your eval job has completed with return code 0.

3
fading ermine
#

:o

dusky pewter
#

hi what are the best content to start with unit testing and penetration testing?

potent quest
#

!d contextlib.redirect_stdout

bitter wadiBOT
#

contextlib.redirect_stdout(new_target)```
Context manager for temporarily redirecting [`sys.stdout`](https://docs.python.org/3.10/library/sys.html#sys.stdout "sys.stdout") to another file or file-like object.

This tool adds flexibility to existing functions or classes whose output is hardwired to stdout.

For example, the output of [`help()`](https://docs.python.org/3.10/library/functions.html#help "help") normally is sent to *sys.stdout*. You can capture that output in a string by redirecting the output to an [`io.StringIO`](https://docs.python.org/3.10/library/io.html#io.StringIO "io.StringIO") object. The replacement stream is returned from the `__enter__` method and so is available as the target of the [`with`](https://docs.python.org/3.10/reference/compound_stmts.html#with) statement:

```py
with redirect_stdout(io.StringIO()) as f:
    help(pow)
s = f.getvalue()
```  To send the output of [`help()`](https://docs.python.org/3.10/library/functions.html#help "help") to a file on disk, redirect the output to a regular file...
marsh raft
#

if I were you, I'd test that your function generates the right data, and just assume that it properly writes it as JSON, since doing that is quite easy and therefore not really worth testing

#

I mean, run your stuff by hand a couple times to make sure it's writing out the JSON, but there's no need to unit test all that

#

you should write tests that have genuine benefit

#

as opposed to testing every conceivable thing your code does

#

i/o is notoriously difficult to unit test

#

and mocking and patching are tricky to get right

#

if I were you, I'd assume the built-in JSON libraries work correctly.

#

It happens to be true, and assuming that will save you a pile of effort

#

I'm imagining that you have a function like this ```py
def compute_a_buncha_stuff_then_save_it_as_JSON(inputs, output_file_name):
...

#

if so I suggest you rewrite it just a little like this ```py
import json

def compute_a_buncha_stuff_then_return_it_as_a_list_of_dicts_or_something(inputs):
...

def compute_a_buncha_stuff_then_save_it_as_JSON(inputs, output_file_name):
stuff = compute_a_buncha_stuff_then_return_it_as_a_list_of_dicts_or_something(inputs)
with open(output_file_name, 'w') as outf:
json.dump(stuff, outf)

#

then test that first function, and assume that the second one works fine

#

look at that second function: it does two very simple things. The first thing it does, you've thoroughly tested; the second thing is built into python, and therefore doesn't need testing. It has no ifs or loops or anything. Guess what: you don't need to test it

#

ok ok you should run it once or twice just to make sure there's no brainos. But you don't need anything beyond that.

#

this is just a taste of what's called "Test-Driven Development". I'm not a True Believer, but there are some good ideas in there

marsh raft
#

well, 100% coverage would be great; it's just that it's not free

#

that last 5% will take a lot of time and add a lot of complexity; it's just not worth it

proper wind
#

with TDD you are just doing your tests first. so you just move where you run your app from to the test file rather than a script you probably using instead.

#

that way you don't have to think really. as the tests drive the code. and most of the unhappy paths get catered for too. as you start with failing tests

#

i.e. if you had a test now called test_write_to_file . your tests will fail

#

so then you make the test pass.

#

by coding that functionality

#

when you code. u normally code the short cut happy path. and run some script that does what your writing it for. but instead of that 'script' . instead run a test

marsh raft
#

that's the ideal.

#

In practice it's often very difficult to do TDD

#

I almost always start out doing it, but sometimes have to abandon it

proper wind
#

agree totally. but i think 90% of people do them wrong. even me. and TDD is a holy grail

#

i mean even think about them wrong

#

when you get it right. you feel the flow. and you realise doing them afterwards is almost pointless

#

and probably tests the wrong things as it wont pick up the unhappy paths

#

and doing them after. might lock in functionality rather than behaviour. it might be a bad thing

marsh raft
#

in theory you're not supposed to test the implementation, and instead just test the contract. I understand the reasoning, but again it's often hard to do that right

proper wind
#

anyone here read obey the testing goat?. i quite enjoyed that one

marsh raft
#

sounds familiar

#

sounds like the sort of thing whose examples are in Smalltalk or something though πŸ™‚

proper wind
#

i think it was django 2. and i did it but converted it to django 3 but followed along. made it a little hard

marsh raft
#

yeah just found it myself.

#

pretty well written, I gotta say

proper wind
#

ye the first several chapters are easy. then it ramps up a bit

#

as i recall

tender venture
#

Hey folks, we are launching a npm package in beta, it generates unit tests in bulk for JS TS and Python. We hope to accelerate the unit test production and make developer life a bit easier. https://www.producthunt.com/posts/ponicode-cli check it out and share your feedback

Product Hunt

Faster software development, more robust code & high code coverage directly from your command line are now possible thanks to AI. Generate unit tests in bulk for your TS, JS & Python projects with the most relevant test scenarios. https://www.npmjs.com/package/ponicode πŸŽ‰

pearl cliff
#

i'd be curious what the underlying ML model is like

#

ah, i see

Ponicode CLI accelerates developers by- creating and bootstrapping your unit test file with a test suite per function - writing 5 test scenarios for each functions- including both happy paths & edge cases to each test suite.

#

so it's not like mutation testing, fuzzing, etc. where it generates a huge amount of inputs

#

it "just" auto-generates tests for your code when you don't already have tests

#

is this built on copilot or is it something different? where did you get the training data?

vernal bison
#

not sure it's a good idea. maybe it is if your boss insists you need to have the coverage just because and you have to do it, but for the sake of the code being correct it really makes more sense to apply unit-tests wisely and make sure they are correct firstly and don't overdo with it, then you can refactor it, etc, then it's really useful

#

if I understand it correctly, it will just copy the code to the unit-test framework

#

talking about edge cases makes sense, but the problem with that is: YOU have to DEFINE what you expect it to do in those cases, should it stop working/continue working as much as possible/inform/etc ?? it's the matter of design and you need to agree on that when you're coding

#

well, it creates the points for you, so maybe good at elast that, you don't need to type much and then read carefully and make decisions... I guess

vernal bison
#

many companies blindly apply that the coverage needs to be at least that percentage or as much as possible, but it's silly, if you are keeping good architecture and things are good decoupled then you surely don't test everything (like you don't need to test every method, etc), you test things that are not very clear, complicated or if your design has agreed on a specific rule/goal/result

#

if you change one method and it brakes another method in another class then yes, you test it, but it's probably solvable even better by changing the architecture and decoupling things

pearl cliff
#

i recently saw it said that code coverage metrics are most useful when you are first starting a project, because they show you all the parts of the codebase you forgot about when you started writing your test suite

vernal bison
#

but blindly copying the same logic to the unit-test doesn't make the logic any better... the key point of unit-test is testing if the logic is correct, but you can't do it with the copied logic, that was my whole point of argueing that coverage test alone does not mean anything if you are not aware what you are doing

#

in the end, I did not try the project, maybe the project does work differently than I am imagining, in that case my apologies

#

best examples when the unit-tests are helpful is about CONSISTENCY: for example, if you only add positive numbers then your sum must also be positive, if you get a negative number then it's a consistency violation, or let's say you only add even integers, then the sum must also be an even integer, or if you calculate probabilities of something and it can happen only one of them, in that case adding them up must be exact;y 1, things like that

#

if you have a big project, very often consistency checks lead to discovering bugs that are there for a long time and you don't notice them πŸ™‚ a very powerful thing

pearl cliff
#

It sounds like you're talking about testing "properties"

#

And I agree, that's a better way to test

#

I think in this case it just generates "5 test cases" for you

#

Unclear if those are properties, or individual examples, or both, but i would guess it's the latter

#

I guess one of us could try it πŸ˜†

tired jewel
#

hi

#

what wrong with this doctest line

#

@low pagoda

low pagoda
tired jewel
#

you are a helper

low pagoda
#

I am helping when I am able to do it

#

Please, don't ping random people

tired jewel
#

ok sry

pearl cliff
#

So it thinks the rest of the line is a string, but it doesn't find the end of the string

tired jewel
#

Fixed

#

thx

#

why the ellipsis not working here

pearl cliff
tired jewel
#

i know the error message why it happenning

#

it's the expected output

#

and it should pass the tests not fail

pearl cliff
#

Ah, sorry then

#

Let me see

#

it looks like ELLIPSIS doesn't have any effect for tests, but it does look like the traceback needs to be indented

#

i'm not sure about the 2nd ellipsis, let me read further

tired jewel
#

ok

#

yea it works

pearl cliff
#
>>> r = add_integer()  # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
    ...
TypeError:
#

that should work

#

When the IGNORE_EXCEPTION_DETAIL doctest option is specified, everything following the leftmost colon and any module information in the exception name is ignored.

tired jewel
#

this is what i did

    >>> r = add_integer() # doctest: +ELLIPSIS, +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    TypeError:...

pearl cliff
#

the ... in TypeError is ignored

tired jewel
#

oh yea

pearl cliff
#

and the +ELLIPSIS has no effect here

#

it also looks like youre expected to indent the ...

tired jewel
#

but it still works

#

thank you so much

#

it indent it by it self

pearl cliff
#
def add_integer(a, b):
    """ Add integers

    Example:
    >>> r = add_integer() # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
        ...
    TypeError:
    """
    return a + b
tired jewel
#
    r = add_integer() # doctest: +ELLIPSIS, +IGNORE_EXCEPTION_DETAIL
Expecting:
    Traceback (most recent call last):
        ...
    TypeError:...
#

why can't i do something like this

    >>> r = add_integer() # doctest: +ELLIPSIS, +IGNORE_EXCEPTION_DETAIL
    ...:
        ...
    TypeError:
pearl cliff
#

i think doctest just requires Traceback (most recent call last):

#

that's just how they decided to do it πŸ€·β€β™‚οΈ

#

think of it like a pattern that the output has to match

tired jewel
#

ok thx

magic dawn
#

okay, so I would say, first

loud lark
#

In TDD, How do you know what tests to write when your logic is changing

magic dawn
#

that there are degrees of TDD?

#

there's the Super-Hardcore-Make-Sure-Compile-Fails-And-Always-Write-Tests-First style

#

I'm not a fan of that

#

and in particular, when experimenting, you don't even know what the intended outcome is

loud lark
#

I feel that's what is advertised generally in most resources

magic dawn
#

so writing tests first can be πŸ₯΄

magic dawn
#

but we're quite practical about it

loud lark
#

Yeah that's exactly how I feel

magic dawn
#

on the other hand

#

there are cases

#

where the intended result is super clear

#

okay, for example

#

I was adding methods to a class that represented a date range

#

so

#

I wanted to add a clip method and a expand method

#

so basically reduce the bounds of the current range if they're outside the passed range

#

and expand the bounds if they're less than those of the passed range

#

in those cases

#

intended behaviour is very clear

#

so TDD, in the sense of "write tests first", works well

loud lark
#

Yeah that's exactly it

magic dawn
#

but

#

it's not only limited to those cases.

#

there is a school of thought that basically says

#

once you have identified a reproducible bug

#

you should write a test case that catches it first

#

and THEN fix it

#

I agree with that

#

because if there was a bug clearly your suite is deficient, right (otherwise it wouldn't have passed)

loud lark
#

I don't see why the order would matter though

#

Why not fix and then write the test

magic dawn
#

your test should actually work

#

because

loud lark
#

oh i see

magic dawn
#

if you haven't written a conforming implementation

#

your test should fail, right

loud lark
#

right and you want to catch the bug again down the line

magic dawn
#

so if you haven't seen your test fail with your existing code, how do you know it actually catches the bug?

loud lark
#

So do you remove the test once the bug is fixed?

magic dawn
#

just like you don't remove your tests once your code is working

#

because your tests are there to assure you of your code's functionality

#

even in the face of further changes

loud lark
#

but wont the test fail?

magic dawn
#

i.e. to catch regressions

loud lark
#

or is that a scenario where you want it to fail once it is fixed?

magic dawn
#

say you have a function divide(a, b)

#
def test_divide_int():
    assert divide(6, 2) == 3

def test_divide_float():
    assert divide(3, 2) == 1.5
#

and assume further that you want to have special behaviour for dividing by 0: you want your function to return 0

#

but you didn't write a test for that

#

so in production, there's a divide(13, 0) somewhere, and that throws a ValueError instead of returning the expected 0

#

now you know you have a bug

#

step 1: add to test

def test_divide_zero():
    assert divide(5, 0) == 0
#

and now, when you run your tests, this one will fail

#

THEN you fix your divide function

#

and you know it works when your test passes

magic dawn
loud lark
#

I see now that makes sense

magic dawn
#

that said, actually writing tests is a lot more important than when you write them, IMO

loud lark
#

Thanks so much for the explanation

magic dawn
#

the nice thing about writing tests first is that you can be sure they all fail (as they should)

#

np! πŸ™‚

magic dawn
#

I HATE writing tests

loud lark
#

You should turn this set of messages into a medium article for the jr devs

magic dawn
#

I actually would like to start blogging but I don't know if anyone would follow me

loud lark
#

Yeah those of us whose managers decide to get more into TDD so we scout the net to understand why do this

#

Well you’ve got an audience here at this discord server for a start

magic dawn
#

all right

#

I will see if I can come up with something

#

you wanna know when it's done

#

?

loud lark
#

Yeah ping me please

burnt whale
#

How to mock os.path.exists called inside certain function in my music.py file?
@mock.patch("music.get_track_paths.os.path.exists") do not work (causes ModuleNotFoundError: No module named 'music.get_track_paths'; 'music' is not a package_ error)

proper wind
burnt whale
#

Unfortunately, I have to return two different values for this check (one inside the mentioned function and another one in an another function) - so have to specify function' name

#

In other words - I have to differentiate between two calls of os.path.exists (and, unluckily, two opposite values πŸ˜… ) in one unit test

#

code_file.py

import os


def second_function():
    return os.path.exists("/foo/bar")


def my_function():
    second_inside_call = os.path.exists("/i/love/mocking")
    if not second_function() and second_inside_call:
        return True
    return False
#

test_file.py

from code_file import my_function
from unittest.mock import patch


@patch("os.path.exists", return_value=False)
@patch("code_file.my_function.os.path.exists", return_value=True)
def test_my_f(first_mock, second_mock):
    assert my_function()
#

Good luck - both for you and me πŸ˜„

buoyant latch
#

Use side_effect.
This is copied from the python docs (https://docs.python.org/3/library/unittest.mock.html):

>>> def side_effect(value):
...    return value + 1
>>> m = MagicMock(side_effect=side_effect)
>>> m(1)
2
>>> m(2)
3

Since you have the parameters (value) you can do different things in the side_effect function.

To apply this you can either do

@patch("os.path.exists", new=m)
def ....

Or

@patch("os.path.exists")
def test_my_f(first_mock):
    first_mock.side_effect = side_effect
    assert my_function()

I think.

burnt whale
#

Still - how to differentiate calls?

buoyant latch
#

Like i said, by looking at the value, or i guess you could look at the call_count inside... there is no pretty solution afaik.

burnt whale
#

It could be cheeky - but give me a working test (test_file.py) with correctly passed assert, I politely please πŸ˜„

pearl cliff
#

Replace os.path.exists with your own function

#

Use the new=my_special_function argument

burnt whale
pearl cliff
buoyant latch
#

I meant something like this

m = Mock()


def side_effect_1(path):
    if m.call_count > 1:
        return True
    return False


def side_effect_2(path):
    if path == 'exists':
        return True
    return False


m.side_effect = side_effect_1
# m.side_effect = side_effect_2


class Dummy:
    @staticmethod
    def func(path):
        return path


@patch.object(Dummy, "func", new=m)
def test_this():
    assert Dummy.func("nope") is False
    assert Dummy.func("exists") is True

(Dummy class only exists for me to have a namespace to use with the @patch)

However, both side_effect solutions are - in my opinion - fairly ugly as the mock needs to "know" a lot about how the code works. Perhaps mocking second_function altogether is a better solution.

(edit).. actually side_effect_2 could be alright

burnt whale
burnt whale
tired jewel
#

hi

#

why the test is not matching what it is expected

#

help me pls this makes no sense

pearl cliff
tired jewel
#

pls anyone

#

salt

#

oh

#

😫 sorry

burnt whale
#

My written downloader service uses two different checks:

  • one for existence of ready to play tracks (ffmpeg for converting them from any format requires already made directory) directory
  • one for existence of downloading track - do not download it again πŸ˜‰
    So the calls (and its path arguments) are different
burnt whale
# tired jewel

Do you need catch an exception during testing or so?
What do you want to achieve?
The code isn't self explanatory πŸ˜•

pearl cliff
# tired jewel pls anyone

sorry, i truly dont know what the issue is. but i do think that the +ELLIPSIS isn't necessary here, the ... is always recognized

#

are you missing a : in the Traceback line?

#

at the end, after )

#

try fixing that

pale sierra
#

πŸ‘‹πŸ» hello

brittle brook
#

Hey everyone πŸ‘‹
I want to implement unit testing in my project mitype.
Here is the link to the project - https://github.com/Mithil467/mitype

I am very new to unit testing and have learnt basics of pytest and am planning to use it. But apart from that, can someone give me some pointers/tips to what should I be aiming for with this kind of a project? Is there anything I should know before starting out? Maybe some existing project out there that I can refer to.

pearl cliff
#

@brittle brook write your code to do as little i/o as possible "internally" - push as much of the console and disk interactions to the "edges" of your application as possible

#

Use dependency injection so you can explicitly pass in mock things instead of using patch

#

And consider using pexpect to test the actual CLI/TUI

pale sierra
#

Hey @pearl cliff

marsh raft
#

shudder ... "pexpect"

brittle brook
#

Thank you very much! @pearl cliff

knotty flume
#

hello im trying to make a unit test ```py
import unittest

def add(x, y):
"""Add Function"""
return x + y

def subtract(x, y):
"""Subtract Function"""
return x - y

def multiply(x, y):
"""Multiply Function"""
return x * y

def divide(x, y):
"""Divide Function"""
if y == 0:
raise ValueError('Can not divide by zero!')
return x / y
def if_string(x,y):
pass
"""check if string is entered function return error"""

class TestCalc(unittest.TestCase):

def test_add(self):
    self.assertEqual(add(10, 5), 15)
    self.assertEqual(add(-1, 1), 0)
    self.assertEqual(add(-1, -1), -2)

def test_subtract(self):
    self.assertEqual(subtract(10, 5), 5)
    self.assertEqual(subtract(-1, 1), -2)
    self.assertEqual(subtract(-1, -1), 0)

def test_multiply(self):
    self.assertEqual(multiply(10, 5), 50)
    self.assertEqual(multiply(-1, 1), -1)
    self.assertEqual(multiply(-1, -1), 1)

def test_divide(self):
    self.assertEqual(divide(10, 5), 2)
    self.assertEqual(divide(-1, 1), -1)
    self.assertEqual(divide(-1, -1), 1)
    self.assertEqual(divide(5, 2), 2.5)

    with self.assertRaises(ValueError):
        divide(10, 0)

if name == 'main':
unittest.main()``` i made a unit test so it gives an error if u divide with 0 i want to make a unit test now if there are entered string and not number

#

can some one help me

hasty kindle
maiden pawn
pearl cliff
#

In unittest you can just loop over parameters and use self.subTest at each pass

tired jewel
frozen obsidian
#

hello since this is a testing channel

#

I have a question related to pytest

unreal plank
fleet fog
#

Chjj bebsd hddd

#

What is the q

#

Pyton

proper wind
#

Hi, I'm pretty new to testing. I'm using pytest and I want to test the following function and other's like it:

def get_users(path_to_file: String) -> list:
    df = pd.read_csv(path_to_file, names=['l_name', 'f_name'], header=None)
    users = [] 
    for _, u in enumerate(df.values):
        users.append(f'{u[0]},{u[1]}')
    return users

So far I have the following attemtp to verify the return is a list but it fails with a file not founs error

def test_get_users():
    arg = "some file path"
    assert isinstance(get_users(arg), list)

I cound do with some guidance on this, can I create a fixture or a mock file to test this and other functions with?

frozen obsidian
unreal plank
#

Nah

#

they don't last long enough, just ask here

unreal plank
frozen obsidian
#

so like I am trying to test this function
that draws a circle, I am trying to check the parameters

unreal plank
#

ok

frozen obsidian
#
def test_draw_shape_circle():
    """This will check if the circle fits within our boundaries """
    shape, color_code, x, y, length, height = draw_shape(shape="c", color_code="green", x=-250, y=0, length=70,
                                                         height=90)
    assert shape == "c"
    assert abs(x) > 400, "your staring point is not within the bounds"
    assert (abs(x) + length) > 400, "your length is not within the bounds"
    assert y > 400, "your staring point is not within the bounds"
    assert (y + height) > 400, "your height is not within the bounds"
unreal plank
#

ok

frozen obsidian
#

    def test_draw_shape_circle():
        """This will check if the circle fits within our boundaries """
        shape, color_code, x, y, length, height = draw_shape(shape="c", color_code="green", x=-250, y=0, length=70,
>                                                            height=90)
E       ValueError: not enough values to unpack (expected 6, got 5)

test_drawing_shapes.py:18: ValueError
=================================================================================== short test summary info ===================================================================================
FAILED test_drawing_shapes.py::test_draw_shape_circle - ValueError: not enough values to unpack (expected 6, got 5)
#

HOW

frozen obsidian
#

the thing is the other function worked

#
def test_draw_shape_rectangle():
    """This will check if the rectangle fits within our boundaries """
    shape, color_code, x, y, length, height = draw_shape(shape="r", color_code="red", x=-100, y=100, length=150,
                                                         height=90)
    assert abs(x) < 400, "your staring point is not within the bounds"
    assert (abs(x) + length) < 400, "your length is not within the bounds"
    assert y < 400, "your staring point is not within the bounds"
    assert (y + height) < 400, "your height is not within the bounds"
unreal plank
#

can you show the end of draw_shape ?

frozen obsidian
#

this one worked

#

ooh lemme see what I have returned lol

unreal plank
#

hehe

frozen obsidian
#

scfsecfnse sejn

#

yup I forgot to return something lol

#

shape-

unreal plank
#

oh xD

#

you figured it out?

#

too few return items?

frozen obsidian
#

yup wait I am changing it rn lemme check

unreal plank
#

cool

frozen obsidian
#

ayy

#

woked

tight scaffold
#

Pycharm printed its loaded my rc file in coverage, but it didnt actually load it, how to fix this? cos in cmd it works fine but not in pycharm coverage

north stratus
#

Would anybody be able to help out with this?
I need to write an unit test and I should mock everything

 def _dispatch(self, url: str, payload: dict) -> Any:
        self.__logger.debug(f"Sending  request : {payload}")
        token = self.__auth_service.auth(scope=self.__cognito_scope)
        response = self.__http_client.post(full_url=url, auth=token, request_json=payload)

        return response

The thing is, I've never done any of that...

pearl cliff
#

Yeah you will need to mock auth service and http client. That said why use __?

#

Speaker: Lisa Roach

One of the most challenging and important thing fors for Python developers learn is the unittest mock library. The patch function is in particular confusing- there are many different ways to use it. Should I use a context manager? Decorator? When would I use it manually? Improperly used patch functions can make unit tests us...

β–Ά Play video

"Speaker: Edwin Jung

Mocking and patching are powerful techniques for testing, but they can be easily abused, with negative effects on code quality, maintenance, and application architecture. These pain-points can be hard to verbalize, and consequently hard to address. If your unit tests are a PITA, but you cannot explain why, this talk may b...

β–Ά Play video
#

!d unittest.mock

bitter wadiBOT
#

New in version 3.3.

Source code: Lib/unittest/mock.py

unittest.mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.

unittest.mock provides a core Mock class removing the need to create a host of stubs throughout your test suite. After performing an action, you can make assertions about which methods / attributes were used and arguments they were called with. You can also specify return values and set needed attributes in the normal way.

royal wren
#

Hi, what’s the best way to test APIs in Python? I’m using Postman. Should I hit the API directly or test from my local host?

rose oyster
proper wind
#

how to unit test

maiden pawn
#

and using testing client/library special to the API framework you use

loud geode
#

Hello, I am trying to create an automarker for a course I am teaching this semester, I am looking into mock and patch. I am able to mock input with a sequence of inputs in https://pastebin.com/JmKtjv11 , but when I try to separate the testing from the students submission file I am confused about how to apply the patch function https://pastebin.com/70NWfauG . Would anybody be able to give me some pointers? Additionally once I am able to mock the inputs, does anybody have any advice on how to mock print statements so that each print statement is stored in a list which i can compare against the model output?

Note that due to the universities online code environment I cannot install any additional packages or software without a lot of headache, so would prefer to get this implemented with core python if possible

maiden pawn
#

Are students allowed to see and run your tests?

loud geode
#

Yes

#

The way our system works is that we define a number of criteria and then create a CSV which puts a 1 or a 0 as to whether they met the criteria, so assuming that the student passes the test they would be given a 1

#

But I would like students to be able to test with predefined inputs with known outputs

#

and then running on random inputs at the end

#

But am having trouble figuring out how to patch inputs so that they are given in a sequence

#

The code in my first pastebin achieves this when I simply mock input, but cannot figure out how to do this in a separate file in a more unittest way (the second pastebin)

#

Since this is a very beginner course I would like to keep any unnecessary to the problem code out of the file where they will write the solution

maiden pawn
#

IMO a bit of dependency injection would look good here.

loud geode
#

Would you mind explaining this?

maiden pawn
#

A moment, going to reach pc, smartphone is not comfortable

loud geode
#

Thanks!

maiden pawn
#

run tests as python3 -m doctest -v filename.py

#

out of curiosity lets try to finish your way too

#

Oh and we can simplify your case further with

#

this parameter injection version requires even less code to do that

#

so... lets see next way..

loud geode
#

Will have a look through both now!

#

One caveat is

#

Is there a way to do this kind of testing without the code being in a function?

#

Functions will be fine in a few weeks, but right now I am teaching absolute beginners from humanities subjects

#

So trying to keep things as basic as possible

maiden pawn
#

heh, you are making the challenge

#

write testing without functions and without third party packages

loud geode
#

If needs be I can just wrap the code in a function and add comments saying #DO NOT CHANGE THIS

#

haha

maiden pawn
#

I think it should be possible

loud geode
#

Another caveat is, in your code you replace input() with input_number(), is it possible to have it remain as input()?

#

To avoid having to explain that these are special functions which have been created for assignments

maiden pawn
#

I think it should be possible

#

a moment. researching

loud geode
#

E.g. in the first pastebin I posted, the input() is not the builtin input but a mock to replace it, but it appears as if it's the builtin to somebody who doesn't know how to check

#

Ok I have it working!

#

Did require a function though

maiden pawn
loud geode
#

Oh nice

#

I'd love to see how you did it

maiden pawn
#

example.py

amount_of_people = int(input())
for person_number in range(amount_of_people):
    name = input()
    print(f"Hello {name}, you are person {person_number + 1} to check in today")

testing.py

import subprocess
from sys import stdout

result = subprocess.run(
    ["python", "example.py"], input=b"3\nMiles\nBecca\nGeorge", capture_output=True
)

answer = b"Hello Miles, you are person 1 to check in today\nHello Becca, you are person 2 to check in today\nHello George, you are person 3 to check in today\n"

assert result.stdout == answer
print("the result is correct!")
#

run python testing.py as a test run

#

blackbox testing ;b

loud geode
#

This is somewhat similar to what my predecessor gave me!

#

A bit simpler though

maiden pawn
#

to make it more beautiful we could split the lines

maiden pawn
# loud geode A bit simpler though
import subprocess
from sys import stdout

input_lines = [
    "3",
    "Miles",
    "Becca",
    "George",
]

result = subprocess.run(
    ["python", "example.py"],
    input=str.encode("\n".join(input_lines)),
    capture_output=True,
)

answer_lines = [
    "Hello Miles, you are person 1 to check in today",
    "Hello Becca, you are person 2 to check in today",
    "Hello George, you are person 3 to check in today",
]
answer = str.encode("\n".join(answer_lines) + "\n")

assert result.stdout == answer
print("the result is correct!")
#

as a more elegant way

loud geode
#

Nice

#

Seems like I have a few options

#

Thanks for your help!

maiden pawn
#

u a welcome. πŸ˜†

#

a bit of lesson to me too

#

in situations like that I needed apt install expect before

#

(interacting with external process that requires manual input)

#

now I know how to go without it

loud geode
#

haha

#

nice

naive fulcrum
#

hey i am using sqlalchemy and unittest and trying sqlalchemy mocking libraries to mock session execute of select objects

#

having difficulty ... anybody have any advice or have done this before?

naive fulcrum
burnt whale
#

How to mock an inner function?

def a():
    def b():
        return "I want to be mocked"

    print("sth")
    result = b()
    if result is not None:
        print(result)
    assert result is None
    print("Nice")
#
from unittest.mock import patch
from sth import a # import ^ a() function


@patch("sth.a")
def test_if_properly_mocked(mocked):
    mocked.return_value.b.return_value = None
    a()

Unfortunately, don't work 😦

twin shale
#

I have never used mock, but I would have guessed: mocked.b.return_value since b is just inside a which is mocked in this case

#

(is it strange that I started "I want to be mocked" in the melody of I want to break free)

burnt whale
#

Soooo... no, isn't working πŸ˜„

twin shale
#

ok, so what was not working in your code?

burnt whale
#

Try it on your own, seriously πŸ˜„

plush vale
#

I don't think it's possible to patch b from outside a in your example; there seems to be some confusion in the SO thread about what a nested function is

#

b does not get defined until a runs

#

it's no different to:

>>> def a():
...   b = 5
#

is there a reason for b to be defined inside a? usually the reason for that is that the inner function cannot be constructed until the outer function is called

burnt whale
#

Exactly as I expect to behave

#

I eventually declared it outside but it's a still good question

plush vale
#

if it can be declared outside then yes that'd be my suggestion

potent quest
#

how to mock an async method in a pytest env?

plush vale
#

are you using unittest.mock to do the mocking? you can use AsyncMock instead of Mock

potent quest
#

ah, no, i was not using that

potent quest
#

how do y'all mock discord py classes for tests?

magic dawn
potent quest
#

the send method of messegable

#

!d discord.abc.Messageable.send

bitter wadiBOT
#

await send(content=None, *, tts=None, embed=None, embeds=None, file=None, files=None, stickers=None, delete_after=None, nonce=None, allowed_mentions=None, reference=None, mention_author=None, view=None)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Sends a message to the destination with the content given.

The content must be a type that can convert to a string through `str(content)`. If the content is set to `None` (the default), then the `embed` parameter must be provided.

To upload a single file, the `file` parameter should be used with a single [`File`](https://discordpy.readthedocs.io/en/master/api.html#discord.File "discord.File") object. To upload multiple files, the `files` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.9)") of [`File`](https://discordpy.readthedocs.io/en/master/api.html#discord.File "discord.File") objects. **Specifying both parameters will lead to an exception**.

To upload a single embed, the `embed` parameter should be used with a single [`Embed`](https://discordpy.readthedocs.io/en/master/api.html#discord.Embed "discord.Embed") object. To upload multiple embeds, the `embeds` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.9)") of [`Embed`](https://discordpy.readthedocs.io/en/master/api.html#discord.Embed "discord.Embed") objects. **Specifying both parameters will lead to an exception**.
potent quest
#

@magic dawn I have a method that takes a messageable object and uses the send command, I want to mock it and pass my mocked object for the test

plush vale
#

I think you basically have two options: make the event loop fixture module scoped, or make your fixture sync and run its own event loop internally to interact with async resources

#

I think theres probably a very good reason for why the event loop fixture is function scoped by default; you dont want eg background tasks leaking across tests, that would be very bad

#

the latter option obviously limits you somewhat but so far Ive been able to work around it

#

eg if you want to connect to a database asynchronously at session scope to prepare it, you can make the fixture synchronous and internally spawn an event loop to do io and then close it

#

you wont be able to pass async resources into your tests because they'd be bound to the wrong event loop, and you may have to eg dispose pooled connections manually before yielding, but ive been able to work around these limitations so far

abstract trellis
#

Hello

#

can someone help me run tests for starlette locally?

#

I'm also not sure how to go about creating a new pull request

#

but my code change is minimal and I need to run the additional tests I've added locally

#

I've never ran a python test so help is appreciated

abstract trellis
#

I think i figured out how to run the test using pytest from the cli

cobalt ore
#

if i have some x = getattr(module, 'thing') and then do getattr(x, 'other_thing') what would I refer to these as?

I'm getting the attribute (thing) from the module, then i'm getting the attribute (other_thing) from the module attribute πŸ€”

I was thinking of calling it:

def get_sub_attribute_from_module( ...

does that make sense?

granite heath
cobalt ore
wary timber
potent quest
#

how do i check a dict is a subset of a different dict?

pearl cliff
potent quest
#

ah cool

cobalt ore
pearl cliff
#

@cobalt ore yes, that's exactly what it does. it depends on what you mean by "subset", and why we don't have more set operations on dicts - because the core devs thought for years that it was potentially confusing. but dicts generally work on their keys, e.g. iterating. and that's how this particular example works: recall that iter(d1) iterates over d1.keys(), and set() just consumes an iterable to produce a set, so set(d1) is really set(iter(d1.keys()))

cobalt ore
unreal plank
#

i'm pretty sure it the whole purpose of a dict is the association, not the set of keys it has

#

it's more an artifact of how python iteration on dicts works--I see no connection to subsets or supersets of mappings

pearl cliff
#

i think it just depends on your intended meaning

#

and you could do set(d1.items()) for the set of key,value pairs (as long as the values are hashable)

#

maybe there's a use case for a "non-hashing set" where it checks for equality the slow way, with ==/__eq__

lean cave
#

Hi anyone have idea about code coverage through pyunits, for example my mail code is doing file handling or writing a file and reading it how can I cover that in code coverage

wide lotus
near lance
#

items() is also, if values are hashable.

cobalt ore
#

But if I hear subset, I think how I explained

#

Which I pointed out as perhaps I'm wrong in thinking in those terms

#

What you're outlining wouldn't be a subset to me, just the keys could be

pearl cliff
hexed cloak
#

and you should tell them to use tox waves stick

abstract trellis
#

What's Tox??

hexed cloak
near lance
#

You specify a bunch of Python versions, and it creates virtualenvs for each, installs your dependencies and your package into them, then runs tests. That way you can know every version works, installing works (since it uses the sdist not direct from your repo), etc.

hexed cloak
long plank
#

Hi, dudes, hope everybody here is ok. I wrote a test for a function that calls zipfile.ZipFile(io.BytesIO(binary_content), 'r'). Every time I run that test I got exception BadZipFile: Bad magic number for central directory. But, if I run the same code outside test, everything is fine. As far as I know, that exception is raised after the following zipfile's check: centdir[_CD_SIGNATURE] != stringCentralDir. I'd like to know if there is a general solution to that problem

#

binary_content variable comes from requests response content

grizzled cape
#

Has anyone faced python selenium headless script failure which works with GUI ? Using detain 11

#

*Debian

potent quest
#

okay wow