#unit-testing

1 messages ยท Page 23 of 1

low pagoda
sly swallow
#

How do I do that. I'm kinda new to testing.

#
from mock import Mock
stdout = Mock()
#

?

#

Is there a good source to learn testing in python?

low pagoda
sly swallow
#

pytest

#

along with pytest-describe

low pagoda
#

If you don't do that you get integrating test pithink

sly swallow
#

So mocking is only for unit tests?

low pagoda
#

In your case you don't need to have working task, you just want to check log method

magic dawn
#

does anyone use contract testing here?

#

just curious

peak palm
#

Anyone know how to make selenium driver global? I have it so in a gherkin before all function. But when it goes to steps.py it forgets that driver should be in context

plain venture
low pagoda
frozen sinew
#

Sorry wrong channel

manic sorrel
#

Is there a way to implement unit tests to a script?; How do I unit test methods that are mainly like the following :

def autobump(self):
        """Automatically bumps items for sale."""
        to_modify = []
        to_bump = []
        try:
            item_ids = [item['item_id'] for item in self.data['inventory']]
        except TypeError:
            self.println("Skipping autobump; no owned items")
        else:
            self.println("Autobump starting..")

            for item in self.data['inventory']:
                if item['sell_price'] <= item['higher_avg'] and item['profit_forfeited'] == False and item['desperate'] == False:
                    if item['last_bumped'] == None or (int(str(time.time())[:-8]) - item['last_bumped']) > 86400: #86400 is one day in epoch
                        to_bump.append(item)
                        to_modify.append(item)
                elif item['sell_price'] >= item['higher_avg'] and item['profit_forfeited'] == False and item['desperate'] == False or item['sell_price'] <= item['higher_avg'] and item['profit_forfeited'] == True and item['desperate'] == False:
                    self.log(f"Sell price is now over max_sell_price, forfeiting profit.")
                    item['profit_forfeited'] = True
                    if (int(str(time.time())[:-8]) - item['last_bumped']) > 259200: ## 259200 represents 3 days in Epoch time
                        to_bump.append(item)
                        to_modify.append(item)
            self.println("Autobump complete")```
swift bough
#

Here we are using the capsys fixture in pytest to "capture" print commands. Pytest is powerful, but overwhelming at first. You will sink a ton of time into writing tests until you know the basics, then it'll get easier to write tests.

def test_myoutput(capsys):
    print("hello")
    sys.stderr.write("world\n")
    captured = capsys.readouterr()
    assert captured.out == "hello\n"
    assert captured.err == "world\n"
    print("next")
    captured = capsys.readouterr()
    assert captured.out == "next\n"
manic sorrel
#

I appreciate your response, So there is no real way to test it except for looking at the print statements?
Thanks, as you said I'll be spending much time learning about this.. Thanks you ๐Ÿ™‚

low pagoda
#

Is there a way to create a pretty id for multiple @pytest.mark.parametrize?

@pytest.mark.parametrize("force", [None, True, False])
@pytest.mark.parametrize("limit", [None, 0, 1])
def test_something(force, limit):
  pass

In result I can see

test_something[None-None]
test_something[None-True]
test_something[None-False]
test_something[0-None]
...

Is there a way to receive something like test_something[limit=0, force=None]?

swift bough
# manic sorrel I appreciate your response, So there is no real way to test it except for lookin...

In your code, you have conditionals that just print things. If you put in an intermediate variable and returned it from the function in addition to printing it, it might look like this:

def my_fun(input):
    ...
    if condition:
        msg = "hello"
    ...
    print(msg)
    return msg

then you could test it like:

def test_my_fun():
    result = my_fun(INPUT_THAT_MAKES_CONDITION_TRUE)
    expected = "hello"
    assert result == expected

You could have multiple conditionals that build the message throughout the function and then print it at the very end.

This would let you assert that the message is what you think it is, without having to "capture" stdout. Or you could just keep your print statements as-is and learn how to use the capsys fixture in pytest.

manic sorrel
#
You could have multiple conditionals that build the message throughout the function and then print it at the very end.```
I've never thought of doing this
swift bough
#

I just modified my answer above to be a bit cleaner.

#

If you decide to build the message over the function, it might look like:

#

!e

msg = "beginning"
msg += "hello"
print(msg)
bitter wadiBOT
#

@swift bough :white_check_mark: Your eval job has completed with return code 0.

beginninghello
swift bough
#

^Except you have to take care of newlines

manic sorrel
#

Oh wow, I didn't know the bot could do that aha

swift bough
#

Looks like "!e" has to be at the top of your comment for it to eval I just found out.

manic sorrel
#

I see, that could come in handy

swift bough
#

Also if you build the message as a list...

#

!e

msg = []
msg.append("line1")
msg.append("line2")
print("\n".join(msg))

*fixed

bitter wadiBOT
#

@swift bough :white_check_mark: Your eval job has completed with return code 0.

001 | line1
002 | line2
swift bough
#

^ The "001" in eval output is line numbers btw

manic sorrel
#

I don't understand why your code originally returned no output

#

was it purely a problem with the bot?

swift bough
#

I didn't print anything initially. Then I edited and printed the list by accident. Then I edited and printed the proper bit, lol.

granite anchor
placid loom
#

does anyone have any tips on how to unit test data pipelines? specifically, i use luigi as a DAG orchestrator and it's kind of awkward to set up unit testing through that. note that i specifically want to check "business logic" kind of things, not data validation (i.e. not something like greatexpectations)

granite anchor
light trail
maiden pawn
#

huh, this pip install coverage
checks for how much of my code branches is triggered during testing?

#

so even if I have barely few tests, but they invoke almost all my program parts

#

it will show a really big percentage?

#

apperently yeah, cool thing

ripe iris
#

How does postman automatically generates cookies for a given end-point and how can I recreate it with something like python requests?

#

I tried response.cookies from requests but it doesn't seem to contain all the cookies like it does in postman's auto generated ones

maiden pawn
# ripe iris How does postman automatically generates cookies for a given end-point and how c...

https://stackoverflow.com/questions/12737740/python-requests-and-persistent-sessions
here looks like an answer

copying
You can easily create a persistent session using:

s = requests.Session()
# After that, continue with your requests as you would:

s.post('https://localhost/login.py', login_data)
# logged in! cookies saved for future requests.
r2 = s.get('https://localhost/profile_data.json', ...)
# cookies sent automatically!
# do whatever, s will keep your cookies intact :slight_smile:
# For more about sessions: https://requests.kennethreitz.org/en/master/user/advanced/#session-objects
ripe iris
#

@maiden pawn not sure if I'm doing it right cause it doesn't seem to work

#

I'm not getting an error but I'm suppose to receive a json object and instead it's throwing html file

#

It works when I do it from postman

#

I'm passing some cookies in my headers aswell btw

maiden pawn
#

I am unsure where I can test it%

ripe iris
#

can I PM u?

maiden pawn
#

well... I guess yeah

#

curious enough to try

swift bough
# maiden pawn so even if I have barely few tests, but they invoke almost all my program parts

Yeah, coverage is a good way to make sure your tests are reaching the dark corners of your code. It's another matter to write good tests that reach the dark corners.

I've only just started using Pytest and really paying attention to coverage. It's taken me about as long to cover 50% of my previously-untested code as it took to write the whole thing in the first place.

I think that fixtures are a great way to conceptualize setup/teardown and ensure test independence.

Also if you're getting into Pytest, definitely make use of pytest.mark.parametrize. It took me a bit to wrap my head around, but I think it's a clean/neat way to get into the various branches of a given function.

daring tree
#

This isn't quite the space for it but I think y'all are the most likely to be familiar with test tools.
Any strong opinions here on BDD tools? I've been looking at behave and pytest-bdd. At a glance I can see that behave is much more popular but also very stale (last release in 2018, yeesh), and pytest-bdd is much less popular but still maintained. Not much for comparisons on the interwebs.

I'm not sure BDD is appropriate for unit testing, but I plan to use it for end to end black box testing.

proper wind
#

how to add costum game activity to bot?

viscid basalt
#

Since we're in #unit-testing - describe desired functionality with tests

#

Then write obscure text until tests pass

royal sparrow
#

can anyone help me with my HTML code

#

?

ancient latch
#

ok I might be getting confused by the name but assert checks if the condition is already asserted right? cause like... it sure doesnt seem like its assigning anything

#

cause when I assert something, I am declaring it and claiming it as valid right? at least in english

#

assert(2 + 2 == 5) I see examples like this, is this just an example? cause when would the number 2 ever not be the number 2?

#

ok I see on stack overflow that it just checks if the expression returns false? So you put things in it that you expect to return true? But why not just put try: Except to catch errors?

azure matrix
#

How would I write test for a function that only initializes a scheduler:

    def file_opened(self, file):
        self.task = task.LoopingCall(self.log, file)
        self.task.start(self.interval)
fast niche
# ancient latch assert(2 + 2 == 5) I see examples like this, is this *just* an example? cause wh...

Assert is just an elegant way to check stuff. And (at least in the unittest library) there are different ways to assert. For example there is assert_called_once, or assert_called_with that make understanding the code easy.

And I don't see how try/catch is a substitute. The whole point is that we say thar something should be true, and if it's not our test has failed and we want it to crash. Assert is similar to writing

if some_stuff != what_I_expected:
    raise Exception
ancient latch
#

OH

#

OMFG OK

#

๐Ÿ™‚ Just to help people like me:
I assert that such and such should be X. Not that it actually is.

dull jay
#

hello

#

I need help on relative import, if it is the problem

#

I'm trying to implement pytest here but get No Module named ... error

#

Can anyone help me on how to fix this? I can't believe this problem takes more time than coding

#

i fixed it

#

relative import so bad... need to study on that

oblique crater
#

Yes, read on documentation in regards to where the default root will hatch - it's related to config or __init__.py. hence may try not having those in tests and it shall go directory upwards. Where crud.py lies. But yeah ultimately docs gives you more options to choose from as well of some posts in blogs about how to make sane project structure that works.

maiden pawn
#

wow. reading

Book by Vladimir Khorikov```
#

at last

#

I start to get it

#

quite good book to reach understanding

#

captivating

umbral flame
#

hey, can anyone help me with pytest. need to develop a framework

low pagoda
umbral flame
#

i need to develop initial level framework for testing

#

it should require ssh module ec2 connections

rocky wharf
#

When driving Firefox with Selenium how in the world do you change your user-agent now a days?

tulip barn
#

Does anyone by any chance know an alternative to vcrpy ( https://github.com/kevin1024/vcrpy )? Looks like I'm trying to do something that seems a bit too "sophisticated" for it ๐Ÿ˜ฆ

GitHub

Automatically mock your HTTP interactions to simplify and speed up testing - kevin1024/vcrpy

maiden pawn
#

AWEEEEEEEEEESOME!

#

Pytest is the best

#

with pytest-xdist

#

it makes possible running all tests in multiple core threading

#

making them super duper fast

#

speed of tests highly matters

maiden pawn
#

when you realize all pytest features, you understand, unittest sucks

quaint stag
#

Does factory_boy allow creating multiple related objects?

cobalt ore
#

I have something which uses google translate API, and there's a notebook which gives an example of the module usage.

I'm trying to ensure that all of the example notebooks in the repository are tested - or at least - they're ensured to run without raising any exceptions.

In this instance (something that uses google translate API) I'm unsure what would be done. As I have an env variable GOOGLE_APPLICATION_CREDENTIALS which the code uses - which is a path to a local JSON key ๐Ÿค”

how is this typically handled? Please ping me ๐Ÿ™‚

maiden pawn
cobalt ore
#

Also - the JSON keys are user level, so presumably we'd make a new key for each example (with the minimal amount of requirements?) and read that? Am not too sure

uneven kiln
#

I was wondering how i could fix this unittest output

#

its giving me the error

#

how do I not access the function directly

subtle gust
#

Does anybody know how to mock django.core.mail.send_mail?

#

I need some help.

maiden pawn
maiden pawn
#

oh yeah, they have it for mail too there

subtle gust
#

Thanks a lot. I will try.

sand remnant
#

Hi there!
I have a question about mocking in python.

async def my_production_function():
    api_class = get_my_api_class()
    data = await api_class.async_call_to_some_endpoint()
    # ... some other operations
    data = do_stuff_with(data)
    return data

Say I need to test my_production_function, how to do go about mocking get_my_api_class and async_call_to_some_endpoint if I don't actually want to initialize (or call) any API ?

#

I am using pytest-mock.
I have managed to patch get_my_api_class
But I can't find a way to patch that async call to async_call_to_some_endpoint

sand remnant
#

It finally worked. In the scope of my test function, here is what is did

mock_class = MagicMock(name="ApiClassMock", spec=ApiClass)  # this is one of the classes that get_my_api_class can return (can also be the abstract class)
mock_class.async_call_to_some_endpoint = AsyncMock(return_value=5) # data will be 5 when the await returns
mocker.patch('get_my_api_class', return_value=mock_class)
subtle gust
maiden pawn
vivid hill
#

Does anyone know where I can find how to do a unit test for a login page? I've never used python or done unit testing before so I'm lost and would like something to reference.

tight geyser
#

Technically that would be an integration test, and you would use something like selenium

frosty spade
#

For those who need to build integration between teams and have a large amount of fake data for testing, check out https://github.com/ghandic/jsf - it has a seamless integration with FastAPI

GitHub

Creates fake JSON files from a JSON schema. Contribute to ghandic/jsf development by creating an account on GitHub.

maiden pawn
#

WOOOHOOO!
I GOT IT!

#

I understood what is the sacral point of writing failing test in TDD as first step!

#

it ensures our brain is thinking how to create structure of the new feature, to be easily testable after that!
well, and to be not forgetting testing

late loom
#

hi, what's the difference between @pytest.mark.xfail and pytest.raises(ExpectedException, func, *args, **kwargs). Both tests will pass if the function returns the expected exception, right?

low pagoda
late loom
low pagoda
late loom
#

awesome, thanks for the help

maiden pawn
#

Than more I am reading the book Unit Testing: Principles, Practices, and Patterns by Vladimir Khorikov
Then more I understand, that I don't just learn how to make better tests, but how to write cleaner and better structurized code, which can be easily tested.

sly swallow
#

How do I write test for a django viewset?

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated, IsManagerOrSuperUser]
    filter_class = FoodieFilter
drifting mirage
#

why does assertRaises method fail without using with?

pearl cliff
drifting mirage
maiden pawn
#

it can do literally everything unittest does, but more and better

drifting mirage
#

i was hoping of having to only rely on what's on the std lib

pearl cliff
#

oh

#

lol

#

because you actually divided by 0

#

you wrote 1 / 0

#

python doesn't capture unevaluated expressions or anything like that

#

the self.assertRaises never even gets called

#

it just fails at the 1/0

#

!e ```python
import unittest

class TestError(unittest.TestCase):
def test_error(self):
self.assertRaises(ZeroDivisionError)

unittest.main()

bitter wadiBOT
#

@pearl cliff :white_check_mark: Your eval job has completed with return code 0.

001 | .
002 | ----------------------------------------------------------------------
003 | Ran 1 test in 0.000s
004 | 
005 | OK
pearl cliff
#

@drifting mirage โ˜๏ธ

hearty dust
#

What's unit testing

pearl cliff
# hearty dust What's unit testing

writing automated tests for specific small "units" of code, usually individual functions. people also use the term to refer more generally to writing automated tests for software. automated testing is an important part of software development, but it can be difficult sometimes.

hearty dust
#

Nice.

fast niche
# drifting mirage `self.assertRaises(ZeroDivisionError, 1/0)` (using unitTest.Testcase class) for ...

so I wasn't happy with @pearl cliffs solution, cause it doesn't actually test anything, but this seems to do exactly what you wanted without using the with statement. Notice that I don't actually call the function, cause I don't include the parentheses after it's name. ```py
import unittest

def divide_by_zero():
return 1 / 0

class TestError(unittest.TestCase):
def test_error(self):
self.assertRaises(ZeroDivisionError, divide_by_zero)

unittest.main()

bitter wadiBOT
#

@drifting mirage :white_check_mark: Your eval job has completed with return code 0.

001 | .
002 | ----------------------------------------------------------------------
003 | Ran 1 test in 0.000s
004 | 
005 | OK
fast niche
#

You know, I was wondering how to do it in one line, without creating a function. I should probably learn what lambdas are, they seem useful

#

I have seen them before, but they looked a bit scary. But now that I started reading about how they work they don't seem that bad

bitter wadiBOT
#

@drifting mirage :x: Your eval job has completed with return code 1.

001 | <string>:6: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
002 | E
003 | ======================================================================
004 | ERROR: test_error (__main__.TestError)
005 | ----------------------------------------------------------------------
006 | Traceback (most recent call last):
007 |   File "<string>", line 6, in test_error
008 |   File "/usr/local/lib/python3.9/unittest/case.py", line 733, in assertRaises
009 |     return context.handle('assertRaises', args, kwargs)
010 |   File "/usr/local/lib/python3.9/unittest/case.py", line 201, in handle
011 |     callable_obj(*args, **kwargs)
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/qomohaqipa.txt?noredirect

fast niche
#

!e

print((lambda a: a + 2)(2))```
bitter wadiBOT
#

@fast niche :white_check_mark: Your eval job has completed with return code 0.

4
fast niche
#

cool

late loom
#

hey folks - what is the difference between unit testing and integration testing? also, I'm thinking of setting up github actions for automatic testing (ci) for my django server. currently, just planning on running unit tests on classes, wondering if there's anything i'm missing conceptually

pearl cliff
late loom
#

i see... so, for integration testing i'll need to emulate a client and make API requests to emulate some sort of "data flow", is that right? I've heard of testing frameworks like jest / cypress for frontend - should they also be a part of the testing? I assume they're more for unit-testing but for JS

#

thanks for the nice explanation btw ๐Ÿ™‚

pearl cliff
#

yeah you can use cypress for stuff like that

#

thats what my company does, anyway

#

although we dont do a whole lot of that kind of testing

#

another version of "integration testing" would be within one codebase, where you maybe are using lots of individually-tested pieces together

late loom
#

alright - i'll have a look at jest / cypress. it's just for a personal project, so if I test some sort of line from frontend -> backend that should be good for learning the concept of integration testing.

#

thanks for the help, much appreciated ๐Ÿ™‚

lusty shore
#

Can someone explain to me unit testing? like when to use those?

#

i mean i watch 10 video in the row

#

explaining how to check if template is in eg. base.html or smth

#

but i know it is, and allways will......

#

Can someone give me Real world project explaining that

glass quarry
#

@lusty shore I strongly recommend this book (free online):
http://www.obeythetestinggoat.com/
it can feel a bit tedious initially, but stick with it, it goes through a real full application using unit tests, integration tests, and all the other stuff

vivid hill
#

So I am getting a "ModuleNotFoundError: No module named 'studentdashboard'" error and I'm not quite sure how to fix it. My test file is test_forms.py and I am trying to test the forms.py whose path is studentdashboard.forms, not sure if i explained this part correctly. I'm thought it did the import right but evidently not ๐Ÿ˜ฆ

pearl cliff
#

@vivid hill what is the actual file structure?

#
./                  <-- current directory
  test_forms.py
  studentdashboard/
    __init__.py
    forms.py

it should look something like this based on what you just described

#

the right file structure will depend on what else you are doing

vivid hill
#

on my desktop, folder student dashboard then forms.py with init.py and a seperate folder of tests with test_forms.py

pearl cliff
#
./                  <-- current directory
  tests/
    test_forms.py
  studentdashboard/
    __init__.py
    forms.py

like this?

#

and how are you running the tests?

vivid hill
#

yes

#

command prompt

#

im not sure if this is right but i do the virtual environment first

#

and then do python test_forms.py

pearl cliff
#
./
  tests/            <-- current directory
    test_forms.py
  studentdashboard/
    __init__.py
    forms.py

so your current directory is tests when you run that command?

vivid hill
#

yes

pearl cliff
#

ok, cd back up to your desktop and run python tests/test_forms.py

#

that should work

#

python only knows to look in certain locations for modules. one of those locations is "the current directory"

#

it does not know to look in other places like "the directory above me"

vivid hill
#

so instead of doing it as (venv) C:\Users\Bacon\Desktop\Student_Dashboard-master\studentdashboard\tests>, i do (venv) C:\Users\Bacon\Desktop\python tests/test_forms.py ?

#

in the command prompt

pearl cliff
#

what is your actual file structure

#

this looks different from what i thought

#
C:\Users\Bacon\Desktop\
  Student_Dashboard-master\
    ???
#

what is the ???

vivid hill
#

i can screenshot, im sorry for not describing it correctly

#

it looks like that

pearl cliff
#

i see

#
cd C:\Users\Bacon\Desktop\Student_Dashboard-master
python studentdashboard\tests\test_forms.py
#

wait

#

that command is right but

#

you have too much stuff in studentdashboard

#

move all the stuff like readme, requirements, setup, etc. out of that directory

#

or are they already outside that directory? it is hard to tell

vivid hill
#

should I make a new folder?

#

it looks like this

#

readme, run, app, are all outside of the studentdashboard directory

#

forms, route, and settings are within the studentdashboard directory

pearl cliff
#

ok, that looks fine

vivid hill
#

my code was based off Corey Schafer's from his Flask Series Code here

#

my imports are like so for the forms.py tho

#
from flask_wtf import FlaskForm
from flask_login import current_user
from wtforms import StringField, PasswordField, SubmitField, BooleanField, SelectField, IntegerField, DateField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError, InputRequired, NumberRange
from studentdashboard.database.models import User, StudentInformation
from studentdashboard.database import db
#

I've been told that a login page would be more integration testing instead of unit testing

maiden pawn
#

hehe, all tests were passed during development
decided to test in postgres in local machine before deploying

#

all tests were failed

#

because max_length constraints were not working in sqlite ;b

lusty shore
#

Hello, for example i have test called test_username_is_unique

#

and my form has about 10 fields unique, Sex, birth_date etc...

#

how should i write test without writing the same fields..

maiden pawn
#

available_apps = ['customer', 'payment', 'plan', 'status']
available_models = [Customer, Payment, Plan, Status]
zipped_apps_and_models = [
    item for item in zip(available_apps, available_models)
]


@pytest.mark.parametrize("app", available_apps)
def test_url_main(client, one_user_and_payment, app):
    "testing main section to choose tables"
    resp = client.get(f'/{app}/', follow=True)
    assert resp.status_code == 200


@pytest.mark.parametrize("app", available_apps)
def test_url_table(client, one_user_and_payment, app):
    "checking farhub table render"
    resp = client.get(f'/{app}/{app}/', follow=True)
    assert resp.status_code == 200


@pytest.mark.parametrize("app, cls", zipped_apps_and_models)
def test_url_change(client, one_user_and_payment, app, cls):
    "checking farhub table renderrender of admin interface to change it"
    objects = cls.objects.all()
    assert len(objects) != 0

    for obj in objects:
        resp = client.get(f'/{app}/{app}/{obj.id}/change/', follow=True)
        assert resp.status_code == 200
#

look at those silly 3 tests

#

which have parametrization

#

that makes them

#

3*4 = 12 tests ;b

#

each test is launched 4 times with different parameters and class objects

#

pytest is awesome

lusty shore
#

hmm

#

thx

prisma forge
#

Hey legends, was wondering if there are any good unittests for dummies guides that youโ€™d recommend?

low pagoda
maiden pawn
#

trying to find good way to test discord bots
besides testing all logic outside of discord framework

#

so far have found only this

#

thinking if I would be too much of a pervert to write my own discord bot testing library

low pagoda
#

You can check how @bitter wadi bot is tested

maiden pawn
#

well, I guess it is time to learn mocks and stabs

lusty shore
#
@pytest.fixture
def user_data():
    return {
        "first_name": "first_name",
        "last_name": "last_name",
        "username": "username",
        "email": "email@email.email",
        "birth_date": now(),
        "sex": "Male",
        "password": "Password123",
    }

@pytest.fixture
def user_registration_data():
    return {
        "first_name": "first_name",
        "last_name": "last_name",
        "username": "username",
        "email": "email@email.email",
        "birth_date": now(),
        "sex": "Male",
        "password": "Password123",
        "password_confirmation": "Password123",
    }
#

is this good aproach?

#

pytest is saying that i cant use fixtures in fixtures....

warm minnow
#

what is wrong with this

lusty shore
#

:

#

after ...+ 1)

hazy idol
bitter wadiBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

warm minnow
#

i didn't understand

low pagoda
lusty shore
#

check !resources

low pagoda
#

Anyway, it's wrong channel to ask about it

lusty shore
#

yep

warm minnow
#

is it correct

low pagoda
#

But yes, it's range(Boundary + 1):

warm minnow
low pagoda
warm minnow
#

brother have you heard of cambridge exams

#

?

low pagoda
#

!topic

bitter wadiBOT
warm minnow
#

ok

#

!rank

bitter wadiBOT
#

Iterating over range(len(...)) is a common approach to accessing each item in an ordered collection.

for i in range(len(my_list)):
    do_something(my_list[i])

The pythonic syntax is much simpler, and is guaranteed to produce elements in the same order:

for item in my_list:
    do_something(item)

Python has other solutions for cases when the index itself might be needed. To get the element at the same index from two or more lists, use zip. To get both the index and the element at that index, use enumerate.

lusty shore
#

is this testing bad?

bitter wadiBOT
stable citrus
#

besides that though, seems pretty reasonable to me
i'm no expert at pytest though
note you have two defs for test_username_max_length btw ๐Ÿ˜›

lusty shore
#

i saw it

#

hahaha

stable citrus
#

Okay I have a question now.
Could someone take a glance at my tests here? Just two short files -- pretty standard stuff
https://github.com/teauxfu/py-hplc/tree/dev/tests

These are unit tests for a package that interfaces with some hardware (HPLC pumps)
I've got tests written for all my methods, and I can run them no problem (in fact, they pass!)

My question is, do you suppose there's a better way I could implement this?
I know most unit tests get run through a CI or similar, but to my knowledge it only makes sense to run these locally.
I know I could mock up the serial connections, but I think that would be essentially fruitless since what I'm really testing is the ability of the pumps to talk with the computer over the serial port. If I write up a script of pump responses to each method/command, all I'd really be testing is my Python syntax...

GitHub

An unoffical Python wrapper for the SSI-Teledyne Next Generation class HPLC pumps. - teauxfu/py-hplc

lusty shore
#

but those tests are good right?

stable citrus
#

I mean yeah they seem reasonable, they don't strike me as 'bad'
again, I'm no expert :p I also came here to ask for advice

lusty shore
#

ok thx

pearl cliff
#

also it's a good idea to refactor your code in 1 of 2 ways:

  1. the high-level pump interaction code should accept a serial connection as a parameter, so you can easily pass in a mocked/faked serial connection for testing. this is a standard technique.

  2. the high-level pump interaction code does not ever interact with a serial connection; instead, it returns a low-level "command" object that can be easily sent over the serial connection by a separate function. this is the "sans-io" technique and it is relatively new and not yet popular (also more complicated).

#
def serialize(cmd, *args):
    ...

class PumpController:
    def __init__(self, serial_conn):
        self.serial_conn = serial_conn

    def cmd1(self, val):
        self.serial_conn.send(serialize("CMD1", val))

    def cmd2(self, val):
        self.serial_conn.send(serialize("CMD2", val))

like this i guess

stable citrus
#

so in regards to 1), am I understanding correctly that you're suggesting

from serial import Serial
from py_hplc import Pump

port = "COM3" # or whatever elese
serial = Serial(port)
pump = Pump(s)

as opposed to passing in the string to init and making the serial connection on my own

#

hmm okay

pearl cliff
#

yeah i think so

#

as a convenience you can have the pump create its own serial connection if the user passes None

#

this way, you can write all your tests for the PumpController by inserting your own serial connection and asserting that the commands being sent are correct

stable citrus
#

hmm okay, that's fair
I did consider doing something like that at first but opted to accept strings instead since it seemed more convenient

pearl cliff
#

and you can simulate responses with errors etc

stable citrus
#

I suppose I could type check the args to init at runtime and either store the serial connection, or build one on the fly if they send in a string

pearl cliff
#

yes exactly

stable citrus
#

or maybe just have an extra kwarg that defaults to None
I was unsure if that would be tacky or not

pearl cliff
#

Pump("COM3") would be equivalent to Pump(Serial("COM3"))

#

that's perfectly fine

stable citrus
#

okay sweet thanks for the feedback

humble steppe
#

lol

proper wind
#

ยฏ_(ใƒ„)_/ยฏ

lusty shore
#
class BaseViews:
    def setup_method(self):
        self.url = ""

    def test_unauthenticated_view(self, client):
        response = client.get(self.url)
        assert response.status_code == 200

    def test_authenticated_view(self, client):
        user = baker.prepare("account.User").__dict__
        user_model = get_user_model()
        user = user_model.objects.create_user(username=user["username"], password=user["password"], is_active="True")
        client.force_login(user)
        response = client.get(self.url)
        assert response.status_code == 302


@pytest.mark.django_db
class TestRegisterView(BaseViews):
    def setup_method(self):
        self.url = reverse("account:register")


@pytest.mark.django_db
class TestLoginView(BaseViews):
    def setup_method(self):
        self.url = reverse("account:login")
#

what do you think about this test?

lusty shore
#

yp?^^^^

pearl cliff
#

Makes sense, I don't particularly love using inheritance like that but I see why you did it

#

If you can make some assertions about the actual content of the view that might be a good idea as well

lusty shore
#

Ok thx

bitter wadiBOT
fierce flare
fiery arrow
#

Question about pytest fixtures:

@pytest.fixture
def available_channel():
    ch = Channel()
    ch.make_available()
    return ch


def test_available_channel_can_be_made_pending_by_providing_usernames(available_channel):
    available_channel.make_pending(caller='alice', called='bob')
    assert available_channel.is_pending()

available_channel is a fixture that creates an available channel (no astonishment yet)
but then I make that channel pending... so it's no longer available, so it's silly to name it available_channel.
How do I proceed?

low pagoda
fiery arrow
#

right, but

available_channel.is_pending()
``` is nonsense in my context
low pagoda
#

Hmm... Then you can create class for this

@pytest.fixture
def available_channel():
    ch = Channel()
    ch.make_available()
    return ch

class TestSomeFancyName:
  @pytest.fixtrue
  def channel(available_channel):
    return available_channel

  def test_channel_can_be_made_pending_by_providing_usernames(channel):
    channel.make_pending(caller='alice', called='bob')
    assert channel.is_pending()

pithink

fiery arrow
fiery arrow
#

One big sad is that type inference doesn't work with fixtures lemon_pensive smh

#

so the question is: maybe I can just call a function?

#
def test_something_important():
    ch = alice_bob_channel()
    ... # boom
maiden pawn
#

so it is supposed to be teared down already

#

if by some miracle, automatic tear down is not working...

fiery arrow
#

huh?

maiden pawn
#
@pytest.fixture
def available_channel():
    ch = Channel()
    ch.make_available()
    yield ch

    print('insert your own tear down of channel here')
#

you can manually destroy channel after the test is finished

fiery arrow
#

I don't need to destroy a channel?

maiden pawn
#

with usage if yield, that temporally transfers control to test

#

errr, all right

fiery arrow
#

yes, I've seen that you can do teardown as well, if that's what you meant ๐Ÿ™‚

#

ah, I see what you mean

#

requiring a fixture as a fixture invokes the teardown as well

#

gotcha

#

makes sense

#

so when you want to add a teardown, you don't have to change every place that uses the fixture

maiden pawn
#

yup

#

just yield ;b

#

useful

maiden pawn
#

that makes pytest just awesome

fiery arrow
#

yep, I know

#

although never used it

limpid summit
#

Is it definitely go with pytest for testing API built on Django Rest Framework, or stick with default one?

maiden pawn
#

I have DRF projects too

#

With pytest my life became much easier

#

DRF is fully compatible to be tested with pytest

tidal kestrel
#

hey all, i have a helper function that is a while True loop. it requests resources from an API until it gets back a response that isn't the max length. i'm trying to write a unit test for it which would request multiple pages but i'm not sure how to mock anything after the first request, any tips?

#
def fetch_order_products(self, order_id):
        page = 1

        while True:
            try:
                order_products_batch = self._request(
                    self.api.OrderProducts,
                    self.BIG_COMMERCE_REQUEST_METHOD_ALL,
                    parentid=order_id,
                    page=page,
                )
                order_products_batch = self._ensure_list(order_products_batch)
                for product in order_products_batch:
                    yield product
            except UnknownIntegrationLogException:
                raise RetryItemException()

            if len(order_products_batch) < DEFAULT_FETCH_PRODUCTS:
                break

            page += 1

thats the helper function, pretty simple.

tidal kestrel
#

also open to "that function is stupid" ๐Ÿ˜…

warm iron
#

like

#

where do the tests GO? in a folder next to mudtelnet? in a file? is there some standard command people use to fire off the tests?

pearl cliff
tidal kestrel
pearl cliff
#

๐Ÿ‘

feral barn
#

Hi all, can anyone tell me how to replace this typing to calmdown pylint 3.8? Current is: 'Optional[List] = None' is that 'Union[List] | None' or something else? thanks

fluid quiver
#

it would be equivalent to Union[List, None]

proper wind
#

Hey, I'm trying to unittest some code using azure-data-table package. I want to patch the 'TableClient' class, but I'm not sure how to achieve this. I'm new to all the patch/mock of objects.

The TableClient has a class-method, named from_connection_string(connection_string, table_name) which returns an instance of TableClient , and ideally I just wanna test the values used as argument.

pearl cliff
#

@proper wind you want to check that from_connection_string was called with certain arguments?

proper wind
fiery arrow
#

@river pilot
I read your article: https://nedbatchelder.com/blog/200710/flaws_in_coverage_measurement.html
I encountered some of that when testing a small (1600 SLOC) project from scratch. Do you have some thoughts or research on overcoming some of those issues?
In particular I'm interested in the "data structures informing control flow thing". For example, a regular expression is essentially a compact program. But coverage tools doesn't check the paths through a regular expression.
Another example, if I return a higher-order function:

expression = one_of(number, string, conditional)
```... there isn't any way of testing if I'm going through all 3 "branches" here.
river pilot
#

I don't have more answers for how to deal with those cases. (And that blog post was 14 years ago!)

fiery arrow
#

damn, 2007 was 14 years ago

#

I'm feeling old...

rustic parcel
#

IMO, the answer to those coverage concerns is generative testing and fuzzing with something like hypothesis. That is, have a computer think of better tests that actually exercise the input space better

vapid stone
inner sedge
#

does anyone have TDD in pdf?

wise matrix
#

Is there an inbuilt @before method that runs exactly once (at the start of test suite) and never again (like @beforeeach.
Simplified example: Initialize a database. Want to do that once and reuse it in all tests.

#

I can probably make something of my own with a boolean variable and call it in @beforeeach ๐Ÿค”

proper wind
#

Hi everyone,
I'm quite new to python unittesting and I'm trying to add a test to a python App. In this app I would like to make sure that the module persist-queue (https://pypi.org/project/persist-queue/) is able to write a message in a FIFO queue based on sqlite database. I don't know exactly where and how to start... Should I use Mock to patch a particular method of persist-queue, how do I have to deal with sqlite ? Any help is very welcome ๐Ÿ™‚

wise matrix
vapid stone
#

once I test multiple methods or classes tgoether it's integration testing already, or?

vapid stone
wise matrix
#

Testing is not by number of tests, it's by ingredients of the test. Do you test a "unit of code" or multiple units of code, does it include external infrastructure such as GUI or a database

wise matrix
vapid stone
#

@wise matrix

proper wind
#

Curretly, the unittest is ran to test that a particular method is able to install an application. In this method i'm using persist-queue, so theire might be no sens to test if persist-queue is working at this point...

wise matrix
wise matrix
rustic parcel
#

if so, then something like this, I think:

@pytest.fixture(scope="session", autouse=True)
def session_setup():
   # setup stuff
   yield
   # teardown stuff
wise matrix
#

Is there something for identifying which test you are in?

#

Example: If it is executing test 5 of 11, i can use "5" inside the test to uniquely identify some things

potent quest
#

aight.

versed iron
#

Hi everyone, please check out this new mock server generator tool that we have developed: https://mockintosh.io

#

It's capable to mock almost every aspects of RESTful APIs and it can even mock asynchronous tasks.

rotund phoenix
#

If you are using namespace packages where do you choose to put your tests directory

versed iron
# pearl cliff OpenAPI support?

The management UI automatically generates a Swagger UI out of your configuration file. Let's say you set 8000 port for the management API with:

management:
  port: 8000

then http://localhost:8000/oas returns the Open API Specification of the configuration YAML. But if you're asking for OAS to configuration YAML then there is no such thing is possible since OAS does not reveal enough information for mocking.

pearl cliff
#

I see, yeah I was hoping for this:

if you're asking for OAS to configuration YAML then there is no such thing is possible since OAS does not reveal enough information for mocking.
Maybe I will need to investigate further into what your tool does, but if I already have an OAS schema then it's kind of "unsafe" to try and copy it all by hand into another config format

versed iron
pearl cliff
#

Ah, that's great. I will seriously have to evaluate this then!

#

Hopefully you'd also consider supporting OAS 3.1 and not just 3.0

#

3.1 adoption has been basically nonexistent for some reason

#

swagger/smartbear seems almost entirely uninterested in supporting it in swaggerhub, swagger editor, etc

#

likewise with postman

versed iron
pearl cliff
#

OK, I need to get back to work but I will try to remember to post an issue later

versed iron
upbeat chasm
#

(selenium) hey, i want to set a local storage key, but it throws an error (Cannot read property 'setItem' of undefined) Why is window.localStorage undefined??

self.driver.execute_script(
            "window.localStorage.setItem(arguments[0], arguments[1]);", key, value)
upbeat chasm
#

got it

#

how can I upload a file in selenium?

fierce flare
junior trench
#

Hello there, I wrote a TypeDecorator for my Database. No i can't import the Module. And I'm also not sure how to call the Decorator. Does someone know how to fix this?

#

import unittest
import password

class TestPassword(unittest.TestCase):
   
   def test_password_is_not_none(self):
       result = password.TypeDecorator('Test')
       self.assertIsNone(result)

pearl cliff
#

what is a TypeDecorator?

junior trench
#

I created a decorator for the form field.

#

class Password(TypeDecorator):

    impl = Text

    def __init__(self, rounds=12, **kwds):
        self.rounds = rounds
        super(Password, self).__init__(**kwds)

    def process_bind_param(self, value, dialect):

        return self._convert(value).hash 

    def process_result_value(self, value, dialect):
        
        if value is not None:
            return PasswordHash(value)

    def validator(self, password):

        return self._convert(password)

    def _convert(self, value):

        if isinstance(value, PasswordHash):
            return value
        elif isinstance(value, str):
            return PasswordHash.new(value, self.rounds)
        elif value is not None:
            raise TypeError(
                'cannot convert {} to a Passwordhash'.format(type(value))
            )

#

I do comment the code later ๐Ÿ™ˆ

pliant void
#

Hi anyone here have experience with the tool called Applitools Eyes?

junior trench
#

Hej, me again. Is there a reason why i can't import my modules in my app.py but not in my Test folder?

wise matrix
#

Might be something with the setup of your directories

junior trench
wise matrix
#

And run all of them as expected

junior trench
#

It doesn't recognise the tests

#

It says no tests at all

wise matrix
#

I've faced this issue a couple of times on IntelliJ and they were solved by fixing the Project Structure. The test folder was not correctly set or some directory was of the wrong type

#

I have a feeling you have the same problem

#

Your imports are working fine (most probably). Something in your setup

junior trench
#

I'm working with an venv and my imports working very finr. Just not in that Test folder

wise matrix
#

Yea, modern ide abstract all that away and give you a button to click which runs all tests. Your ide is not able to make that button for you.

#

Sorry but that's the best I can do. Your imports are working fine, fix the tests and everything should work.

junior trench
#

Okay

#

thx

upbeat chasm
#

How can I handle the "leave site" popup in selenium (chrome)?

pliant void
wise matrix
#

Does pytest not support class variables using self?

pearl cliff
#

@wise matrix can you clarify? this might be a "python syntax question" and not a "pytest question"

wise matrix
#

I have some code to run before test suite and then another bit of code that runs before and after every individual test.
To set some class variable, I used self.

#

Does not work

class Test:
    @pytest.fixture(scope="session", autouse=True)
    def setup_before(self):
        self.flight_index = 0
#
class Test:
    flight_index = 0

    @pytest.fixture(scope="session", autouse=True)
    def setup_before(self):
    # blah blah

    def foo(self):
        print(self.flight_index + 1) # prints correct value
#

but this one does

#

Pytest complained when I tried to make a __init__, wondering what the best way to set these variables is. It is preferred to have them in a method.

#

@pearl cliff

pearl cliff
#

although in this case it shouldn't make a difference, at least i think

#

admittedly im not sure how pytest fixture scoping works

fallen lichen
#

I hope I will get to your level one day, I'm a beginner! Seeing all of this kind of code makes me so motivated to work on my skills @pearl cliff @wise matrix

rustic parcel
#

I think the problem is that there is no instance of Test at the beginning of the session

#

If you want to setup stuff for the whole session and use classes, I think you'd have to set class variables.

#

To find the best idiom, it might help if you gave more detail on what your actual use case is

wise matrix
#

I fixed it temporarily with global to get it to start working

#

Think of it like this,
Create a database at the start of the test suite (and delete at end).
Before every individual test, prepare the database by cleaning up and at the end of each test log some stuff in a txt file.

#

Some nuances, each test is run multiple times (parameterized). Since there is one database, it needs to be single threaded. It is a integration test suite

#

@rustic parcel

rustic parcel
#

@wise matrix Yeah, so you rely on fixture scopes to handle that, and pytest will manage the parameterized tests as appropriate. When I've done that kind of db integration test, I've ended up with a structure something like (from memory here):

# conftest.py in same directory as relevant tests
@pytest.fixture(scope="session")
def database_engine():
   # setup real database
   engine = create_engine(...) # create connection to database
   yield engine
   # teardown real database

@pytest.fixture
def database(database_engine):
   database_engine.execute(<per-test setup>)
   yield database_engine
   database_engine.execute(<per-test teardown)

# in test file
def test_something(database):
    # use the database here
    assert things_are_good
wise matrix
rustic parcel
royal wren
#

Whatโ€™s the simplest way to unit test a requests.post() api call?

maiden pawn
#

in case of not having ability to use it... import requests to local host will work too

spring elm
#

How resource starved are github action containers? Trying to migrate from Jenkins, and see a python -m unittest just hanging, and no log output.

maiden pawn
#
job.<id>.timeout-minutes sets a timeout for a whole job
job.<id>.steps.timeout-minutes sets a timeout for a single step
royal wren
#

I thank you

#

K thanks

spring elm
#

Nvm, I figured it out

royal wren
#

What happens if none of my tests are passing? Is the idea to fix my tests so they pass?

#

Or fix the main code so they pass?

pearl cliff
royal wren
#

Ok gotcha

#

So Iโ€™m testing requests api calls and donโ€™t have valid credentials in my tests

pearl cliff
#

ah, that is a hard situation and there isn't a single easy answer

royal wren
#

Ok thank you

pearl cliff
#

one option is to use a technique called mocking

royal wren
#

Ok

pearl cliff
#

in python, the unittest.mock package gives you the ability to replace any object with a special "mock" object

royal wren
#

Ooh ok interesting

pearl cliff
#

this mock object then lets you inspect function calls that were made, attributes that were accessed, etc.

#

you can even tell the mock to return a certain value if you call it like a function

#

however mocking can get very complicated

#

especially if you are trying to mock an external API - how do you confidently mock an API response without mocking the entire API?

#

perhaps the best strategy is to do as little input/output (i.e. network requests, opening files, etc) inside your code as possible

#

that is, push i/o to the "edges" of your application when possible

#

so most of your code should be perfectly testable, because it just operates on data and returns different data

#

then you only have to worry about using mocking, patching, etc. for the few specific places where you actually perform i/o

#

this is what a programmer might typically write:

def fetch_tags(article):
    tag_ids = article['metadata']['tags']
    response = requests.get(
        'http://api.example.net/v1/tags',
        params={'id': ','.join(tag_ids), 'limit': '5'}
    )
    data = response.json()
    return data['items'][:5]

the problem here is that you are mixing "logic" and "i/o"

#

how do you test that you fetched the right tag ids? how do you test that you post-processed the data correctly?

#

one possible solution is to break up your logic into testable pieces:

def get_tag_ids(article):
    return article['metadata']['tags']

def process_tags(data):
    return data['items'][:5]

def fetch_tags(tag_ids):
    response = requests.get(
        'http://api.example.net/v1/tags',
        params={'id': ','.join(tag_ids), 'limit': '5'}
    )
    return response.json()

this way, you still have to test the full chain of execution at some point, if only to ensure that the preprocessing and postprocessing functions were still applied. but at least you have 2 standalone tests for the data processing, so you can focus on testing the i/o part separately

royal wren
#

This is awesome!!! Thank you so muc

#

Much

pearl cliff
#

one more thing:

def fetch_tags_from_article(article):
    tag_ids = get_tag_ids(article)
    tag_data = fetch_tags(tag_ids)
    return process_tags(tag_data)

at some point, somewhere, we need to mix i/o and program logic

humble wagon
pearl cliff
#

@royal wren so to test this fetch_tags_from_article function, one possibility is to mock your own function.

you could skip trying to mock the API entirely by asserting that the internal fetch_tags function was called with certain arguments. then you return specific data back from it that you control, emulating the case where the function executed successfully.

from mymodule import get_tag_ids, fetch_tags_from_article

def test_fetch_tags_from_article():
    fake_article = ... # make a fake article object
    expected_tag_data = ... # construct the correct expected tag data for this article

    with patch('mymodule.fetch_tags', return_value=expected_tag_data) as mock_fetch_tags:
        actual_result_data = fetch_tags_from_article(fake_article)

        # Assert that fetch_tags() was called with the expected inputs,
        # i.e. test that the inputs are identical to the result of
        # get_tag_ids(fake_article)
        fake_article.assert_called_once_with(get_tag_ids(fake_article))

        # Assert that the result was processed as expected, i.e. test
        # that the outputs are identical to the result of
        # process_tags(expected_tag_data)
        assert actual_result_data == process_tags(expected_tag_data)

here, "patch" is replacing the mymodule.fetch_tags function with one of those mock objects

#

!d g 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.

pearl cliff
#

the docs are here, but they are not easy to read without additional context

royal wren
#

So with using the mock unittesting framework I have this is my test:

#

But getting ModuleNotFoundError: No module named opentok.requests

#

Iโ€™m testing a post request

#

But this works:

@patch(โ€œopentok.OpenTok.muteโ€)

#

If Iโ€™m test sing a post requests inside the mute method is the latter ok or do I need the requests.post ?

rustic parcel
lament spoke
#

I am writing pytests for my API, I have big rather big size of request. Should I separate requests from test_main.py to have less mess in there?

native lava
#

if I were you I would do so

pure prairie
#

Hey everyone.

I prepared unittest for Python bootcamp . I just wanted to learn how new empoleyee can run pytest without see python test file? I meant I wanted to make it automized at all.

My final goal they will push their code on gitlab and on gitlab they can figyre out their result correct and space/time complexity is okay

maiden pawn
#

they shorten tests a lot in #arrange sections, they can be used even in chains

#

plus you could use parametrization

#

it shortens tests even more... for all remaining sections

livid epoch
#

anyone have macos ? I want to test my python library

pearl cliff
#

@royal wren is your module called opentok? And you write import requests inside opentok.py?

royal wren
#

Hi @pearl cliff I was able to figure out the issue. I wasnโ€™t pulling in the top level folder that held my file.

#

Anyone ever use the httpretty library?

I have this code from Pypi and wondering why we do two POST requests? One with httpretty.POST and another with just requests.post.

pearl cliff
#

Is it registering a url to be mocked?

royal wren
#

Hi @pearl cliff yea, I think so. Httpretty is fairly new, and still learning. Thereโ€™s also not as much documentation.

pearl cliff
#

you're not making an extra request

#

the function is called register_uri

#

another option is to use a library called vcr, which does actually make the http request, but then caches the result, so that you get the same http response every time, and it doesn't actually hit a server

#

the advantage there is that you don't need to explicitly do any mocking - you are using real data generated by a real remote server

royal wren
#

Thank you, Iโ€™ll check out vcr as well.

pearl cliff
#

note that there are several libraries for mocking requests

royal wren
#

Ok, Iโ€™m using httpretty for work

#

So Iโ€™ll have to stick with that one but will check out vcr

rustic parcel
pearl cliff
rustic parcel
pearl cliff
#

sometimes i split my tests like this:

  1. mock requests.request or whatever the lowest level interface to the "outside world" is that i can reasonably mock
  2. use assert_called_with (or equivalent) to assert that i called it with the right arguments
  3. use fake data for the return value, and proceed with my tests using that fake data
#

the tradeoff here is that you can end up writing tests that are sensitive to refactoring

#

but refactoring that changes i/o flow is pretty rare in my experience

rustic parcel
#

I like that approach. I often find it hard to get people to write any tests at all before working through mocking strategies with them. On the other hand, I worry I'm providing tools to shoot ourselves in the foot with mocks everywhere. @pearl cliff

pearl cliff
#

@rustic parcel indeed, that's a problem i'm facing right now. i think it's reasonable to set standards and expect devs to follow them, maybe allowing some % of time for self-study in order to achieve that.

#

make testing strategy part of project planning and task sizing

#

and actively discuss with other colleagues

#

pushing i/o to the edges of your application is also an important strategy imo

rustic parcel
#

@pearl cliff yeah, I am working on that with the team (e.g. we are experimenting with OKRs and a big team one is around testing).

pearl cliff
#

at my org i have been talking about standardizing what is and isn't okay/expected to mock, and i think i also want to bring up standardizing how to do the mocking

rustic parcel
pearl cliff
#

yeah ๐Ÿ˜ most frustrating part of software dev imo

#

fortunately our software is pretty simple and most of the mocking is repetitive boilerplate

#

not adding too much abstraction or helper functions too early is important too

#

right now my tests at work are deeply nested mocks, they kind of suck to read and write

#

but i know that they are not the wrong abstraction

#

so to test the entire API end-to-end i'm typically stubbing out the auth code (i do auth testing in a separate class), stubbing out at least one database lookup, and stubbing out a database write. i'm transitioning to replacing the latter two with a real database, and just assuming that the local dev has a copy of our database server running locally, which in our case is a valid assumption.

#

is this the best way? i have no idea

#

is it working? yes ๐Ÿ˜›

rustic parcel
#

I've been pretty insistent about not mocking out the db, so for the e2e tests we pull up a docker container with postgres. works... ok. but i like asking postgres to do stuff it is good at so it ends up being part of the logic.

rustic parcel
pearl cliff
#

basically, you should expect to mock A and B using this helper function, you should never mock C because you should be doing it X way, etc.

potent quest
#

Siiigh.

#

It's the question you never want to ask, but know you must, someday.

#

How to write tests ๐Ÿ‘€
For a website.

native lava
#

"how" is here a wide topic, might wanna be specific?

maiden pawn
#

quite recommending to read

#

10/10 book to get yourself better in understanding tests

verbal void
#

who u, ugly ass mofo

glass quarry
#

great book about making a fully tested django site

maiden pawn
#

hmm, I need web site tested for Safari browser (or apple web rendering engine in general)

#

what is the best way to get it (i can run virtual machines if I will find image)

#

oh yes, I think I was able to find one web site with image for virtual machine

pearl cliff
#

there might be a webkit-based driver for selenium

regal sierra
#

I could really use some help with unit testing in Flask

true adder
#

Can we combine selenium and pytest for webapps?

#

that'd be interesting if we had to run it in... say... Travis CI or jenkins

tight geyser
#

yes you can; pytest is a test runner and selenium is a python library that can be run

maiden pawn
#

absolutely possible

#

pytest fixtures are nice enough to be used for setup and teardown of it

ember maple
#

On ci its OK to use headless selenium or a service container

sleek veldt
#

Hi! I hope you are all doing great. I'm happy to be here, and learn from you and make friends. I'm a newcomer to Python.
I have a question that maybe is not exactly related to unit-testing, but it happened inside a unit-test file. It's about importing functions from other files located in other folders into a test file. I have a main folder with 2 subfolders. One is called GetCounter and the other tests. Inside this GetCounter, there's a __init__.py file. It's an Azure Function that writes to and reads from a CosmosDB database. I want to test a specific function inside this file called getNewCounterValue. In my other folder, the tests folder, I have my test file. I've been trying to import this funtion into this test file, but I always get the same error, that says ImportError: attempted relative import with no known parent package.
How would be the correct way to import that function into this test file? I've tried with from ..GetCounter import getNewCounterValue, and I get the error. I tried with 2 dots, with 3 dots, without any dot... I also tried using sys.path, to no avail.
Thanks in advance. Sorry for the long message.

icy summit
#

Can someone explain why i get this error in travis ci and not locally?
The command "poetry run pytest --cov=broccoli tests/" exited with 4.
i see nothing wrong with that command, i'm using the same syntax with other builds and it works

#
[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
requests = "^2.25.1"
pytest-cov = "^2.12.0"
coveralls = "^3.0.1"
black = "^21.5b1"
#

i can post the traceback if that helps

sour knot
#

Any good books or sites for Python bed

native lava
icy summit
#

I sorted it out, turns out the issue was a missing env variable in travis-ci

#

I have no idea why i got exit code 4 eith pytest however

#

Theres nothing wrong with the syntax of that command

#

Took me like half a day to figure it out because of that bad error

pearl cliff
#

exit code 4 doesn't mean it has to be a syntax error

barren bear
proper wind
#

true

#

true

ivory badger
#

In pytest, the standard convention for passing cmdline parameters to tests is for each option that we add using parser.addoption we have to define a fixture with the same name using @pytest.fixture().
Example:

# In conftest.py:

import pytest

def pytest_addoption(parser):
    parser.addoption("--name", action="store")

@pytest.fixture(scope='session')
def name(request):
    name_value = request.config.option.name
    if name_value is None:
        pytest.skip()
    return name_value

Now what if I want to parameterize and pass a "variable" number of command line arguments (like *kwargs) to my tests using pytest?
Meaning, whatever cmdline parameters I pass to pytest, even if it's not "fixturised" in conftest, should be accessible to my tests: pytest test.py --param1 val1 --param2 val2

As per documents : https://docs.pytest.org/en/6.2.x/reference.html#_pytest.config.argparsing.Parser.parse_known_and_unknown_args
the pytest argument parser does support parse_known_and_unknown_args but I am not sure how to use this in conftest.

kind meadow
#

It looks like pytest appends an argument to the end of the parse with nargs="*", and that this value gets set as request.config.args.

bitter wadiBOT
#

src/_pytest/config/__init__.py lines 1323 to 1331

args = self._parser.parse_setoption(
    args, self.option, namespace=self.option
)
if not args:
    if self.invocation_params.dir == self.rootpath:
        args = self.getini("testpaths")
    if not args:
        args = [str(self.invocation_params.dir)]
self.args = args```
kind meadow
bitter wadiBOT
#

src/_pytest/config/argparsing.py line 129

file_or_dir_arg = optparser.add_argument(FILE_OR_DIR, nargs="*")```
kind meadow
#

I don't see how parse_known_and_unknown_args can be used since pytest does not give direct access to all the raw arguments passed.

past arch
#

it might not be the relevant topic but it is related to it, I am desperate in need of help xd

#

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

import time


#                         SetUP
driver = webdriver.Chrome("C:\Program Files (x86)\chromedriver.exe")
driver.get('http://automationpractice.com/index.php')
actions = ActionChains(driver)

def fooling_around():
    
    target = driver.find_element(By.XPATH("//[@id='homefeatured']/li[3]/div/div[1]/div/a[1]/img"))
    actions.move_to_element(target).perform()
    driver.find_element(By.XPATH("//[@id='homefeatured']/li[3]/div/div[1]/div/a[2]/span")).click()

fooling_around()


pearl cliff
#

is By.XPATH a function?

past arch
#

well it should be

#

I can walk you through what I am trying to achieve

#

I have trying to do this for the last 3 hours

#

click this quick view

#

it only appears when I hover cursor on it

past arch
#

and when this quick view appears,click it

past arch
#

nvm

#

did it

bitter wadiBOT
#

Hey @proper wind!

It looks like you tried to attach file type(s) that we do not allow (.exe). 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.

hallow flax
#

does anyone use the responses library for integration testing? I'v egot a question about it

pliant fable
#

Hi! Anyone has good resources for Advanced Django unit tests? I mostly find beginner stuff, but I want advanced examples, to get a better feeling at the basis to cover regarding views, forms, models, etc. Thanks!

maiden pawn
#

hmm, how to check if static file by url path exists if you ara in pytest django ๐Ÿค”

maiden pawn
#

Fascinating.
for some reason when I launch pytest for all tests, one test is not passed

#

but when I launch this specific test, it is passed

#

I wonder what the hell is wrong with it, not proper isolation between tests perhaps

maiden pawn
#

well, yeah. apperently even if pytest cleaned database between sessions, I should not have requested object with id=1
it got pk=4 due to previous tests.

subtle pivot
#

How do you get PyCharm to run all tests in a project using a hotkey?

barren bear
proven tendon
#
    mocked_requests.assert_called_once_with(
        "{backend}{namespace}/path/my_request".format(
            backend=BACKEND, namespace=NAMESPACE
        ),
        headers={
            "Authorization": "Bearer ACCESS_TOKEN",
            "header-id": "<Some mocked object>",
            },
        json=None, 
    )

How do I accept any mocked object for header_id?

pearl cliff
#

@proven tendon what do you mean "any mocked object"?

#

you can't, really. you might have to manually inspect the call_args list

#
    mocked_requests.assert_called_once()

    expected_url = "{backend}{namespace}/path/my_request".format(
        backend=BACKEND, namespace=NAMESPACE
    ),
    expected_auth_header = {
        "Authorization": "Bearer ACCESS_TOKEN"
    },
    expected_json = None
    call_args, call_kwargs = mocked_requests.call_args

    self.assertEqual(call_args[0], expected_url)
    self.assertTrue(
        expected_auth_header.item() <= call_kwargs['headers'].items()
    )
    self.assertIn('header-id', call_kwargs['headers'].keys())
    self.assertEqual(call_kwargs['json'], expected_json)
#

note that "headers" might be a case-insensitive multi-dict thing and not necessarily a real dict

maiden pawn
#

I want to say words of appreciation to TDD

#

I have no idea how I lived without it before

#

hard (or even next to impossible) changes become simple changes.

verbal void
#

w

proper wind
#

Hi! Probably a noob question, but does it make sense to use the unittest framework to build/run integration tests (in a separate folder/file than the actual unit tests of course)

pearl cliff
#

sure, there's no reason you can't use it for that

#

don't let the name mislead you

proven tendon
maiden pawn
#

shortened time to run tests from 3 minutes to 1 second) in literally almost one line of code.

maiden pawn
#

nothing is more satisfying than running your tests and seeing them all green.
especially during massive refactorization

true adder
#

For pytest, is it better to keep a test module separate from the main package or combine both?

#

Because I have a src package with several submodules

#

So I was wonderif if it was more strategical to have src with test next to each other or nah

pearl cliff
#

test vs tests doesn't matter, choose whatever you like

true adder
pearl cliff
#

@true adder you should make a setup.py for your project and use pip install -e .

#

or use PYTHONPATH=./src

true adder
pearl cliff
#

but yes you should create a venv for every project anyway

true adder
#

The package folder for your Python env

pearl cliff
#

yes, pip installs to the site-packages directory of whatever python installation is running pip

#

basically, i recommend bootstrapping your project with something like this:

#!/usr/bin/env bash

set -eux -o pipefail

project_name="$1"
project_dir="~/Projects/python/$1"
package_name="$( sed 's/-/_/g' <<< "$project_name" )"

mkdir -p "$project_dir"
mkdir -p "$project_dir/src"
mkdir -p "$project_dir/test"

touch "$project_dir/CHANGELOG.md"
touch "$project_dir/LICENSE.txt"
touch "$project_dir/README.md"

mkdir -p "$project_dir/src/$package_name"
touch "$project_dir/src/$package_name/__init__.py"

mkdir -p "$project_dir/test/test_$package_name"
touch "$project_dir/test/test_$package_name/__init__.py"

python -m venv "$project_dir/.venv"
"$project_dir/.venv/bin/python" -m pip install -U pip
"$project_dir/.venv/bin/pip" install -U setuptools wheel

git -C "$project_dir" init
echo '.venv' >> "$project_dir/.gitignore"
echo '*.py[cdo]' >> "$project_dir/.gitignore"
echo '__pycache__/' >> "$project_dir/.gitignore"

echo "Created new project in: $project_dir"
#

(i didn't actually test this script, it's meant to be illustrative)

true adder
#

I see. Because I wanted to try with the datadriven cookiecutter

#

Because they don't have a test package

maiden pawn
# true adder For `pytest`, is it better to keep a `test` module separate from the main packag...

technically tests can be even in each your sub-module of the project.
At least this is how it is suggested by Django by default

[pytest]
python_files = tests.py test_*.py *_tests.py

usually this is how pytest identifies tests
if he is not.. you can create pytest.ini and put it into it

so... feel free to put your tests into folder tests or having them in each your sub module.
it is only a matter of your preferences ๐Ÿ˜‰ pytest is nice, he will understand both your choices.
and both choices people use... sometimes even together.

#

I like pretty much having tests.py in my sub modules.

#

makes usually things easier

#

I put into global tests only tests which are having some sort of parametrization to test all modules together

maiden pawn
#

btw, BDD is myth or truth?

#

wondering if BDD is worthy of its time

proper wind
#

What is Unit Testing ?

maiden pawn
true adder
#

Trying to get a hold of pytest rn. What can I do to define an init function cleaning everything?

#

A fixture?

lament ridge
#

What is unit testing?

pearl cliff
subtle pivot
#

Also see the pins

true adder
#

So I'm using a mock database to store the result of my tests

pearl cliff
#

currently i run a local mongodb database for testing

#

with the ability to tell my application which db to use

maiden pawn
potent quest
#

@versed mortar was seeing your site issue, and what is the differences between unittest and pytest?

#

intentionally here because this question does not apply just to #dev-contrib

versed mortar
#

Well, they are different libs. Unittest is a 1st party module, most prominently used in CPython directly. Pytest is a third party package developed by the one and only Ronny (he's active in places around the server).

Unittest is a pretty flexible module, and supports basically any python version you can think of. Pytest offers basically all what unittests does, and has a few nifty features such as parameterize and fixtures (I'd recommend reading up the pytest page about them). What it doesn't implement, you can usually find in plugins such as pytest-mock for mocking.

Pytest supports unittests out of the box, and has guides for migrating a test suite. It only supports 3.6+ but everything <=3.5 is deprecated so...

potent quest
#

!pypi unittest

bitter wadiBOT
potent quest
#

๐Ÿค”

versed mortar
#

It's first party

#

ships with python

potent quest
#

Unit test is bundled with python?

#

Ah

versed mortar
#

like random for example

#

There are syntactical and semantic differences between pytest & unittest, but those can't easily be summed up, and they aren't as relevant as the high level overview

potent quest
#

Or sys, even

versed mortar
#

ye

potent quest
#

Which is objectively better in your opinion and why?

versed mortar
#

I like pytest because it has the plugin system, and strong fixtures, but you can get by fine with any system really

potent quest
#

Also it's not std lib so it can be updated w/out python version updates lmao

versed mortar
#

Unittest has the obvious advantage of not requiring 3rd party modules, and having long term maintenance from psf

potent quest
#

!pypi pytest

bitter wadiBOT
versed mortar
#

Things in the stdlib are usually very stable

#

I wonder if they have the vanity invite

#

Hmm I'm not sure if they have a public link. Hey @ember maple sorry to bother ya, but do you have a link for the pytest server? If not, I could generate one.

bitter wadiBOT
#

setup.cfg lines 45 to 53

attrs>=19.2.0
iniconfig
packaging
pluggy>=0.12,<1.0.0a1
py>=1.8.2
toml
atomicwrites>=1.0;sys_platform=="win32"
colorama;sys_platform=="win32"
importlib-metadata>=0.12;python_version<"3.8"```
potent quest
#

Copying gh on mobile is hard.

potent quest
river pilot
#

pytest is much more powerful than unittest

potent quest
#

Hello ned

river pilot
potent quest
#

... Does coverage.py's test suite also use itself to check its own coverage?

river pilot
potent quest
#

Ah, let's not get into that right now then lol

potent quest
#

Is using something like coverage.py a good portion of testing?

#

Or is that sometimes just icing on the tests?

river pilot
#

it doesn't change your tests, it's a way of gauging their effectiveness

potent quest
#

So coverage can just be used to run the tests and tells how much of the code ran, with not much extra configuration

#

And to use tests... What are mock attributes and why do we need mock attributes? When is it not always feasible to have the attribute itself and test with that?

versed mortar
#

Are you writing a paper on this? hahaha

Mocking generally refers to mimicking the behavior of a unit, without actually using that unit. That can have many uses. One popular example is mocking a network request. Say you are doing something that makes a request to a site and uses the returned response. Well, making a network request can have overhead and sideffects, which you don't want your test to have. You can mock that request to allow you to test the rest of your behavior.

You can also use mocking to do other things. For example, you can use it to test how your code responds to a certain response, or how it handles errors.

potent quest
#

No I'm not writing a paper on this I've just never written tests

#

And CI is so much fun

versed mortar
#

dw, I'm just pulling your leg

potent quest
#

Lol ik

#

So how are network requests and stuff mocked?

#

Is one way is to take parts of the program and import them into the tests, then monkey patch them to be mock objects?

versed mortar
#

If your code looks like: ```py
def request(url):
return response(url)

def my_function():
resp = request("https://docs.python.org/3/library/unittest.mock.html")
if resp.content == "you should really read that link, it has a lot of useful stuff":
...


Mocking could be taking that `request` function, replacing it with a mock object instead, and when your function goes to call `request`, it'll instead call the mock object of the same name
versed mortar
#

Probably through something like unittest.mock.patch

potent quest
#

love what you did there

versed mortar
#

!unshh

bitter wadiBOT
#

โœ… unsilenced current channel.

orchid ivy
#

wow

lean sky
#

pfft

west axle
#

Ok

carmine geode
#

looks like i was targeted

orchid ivy
#

why were they mentioning everyone?

carmine geode
#

ยฏ_(ใƒ„)_/ยฏ

versed mortar
#

!shh

bitter wadiBOT
#

โœ… silenced current channel for 4 minute(s).

versed mortar
#

I will remind y'all this channel has a topic

#

We had a small raid

#

please ignore it and move on if you don't plan on participating here

#

!unshh

bitter wadiBOT
#

โœ… unsilenced current channel.

sour lodge
#

Hello. Sorry if you were pinged in this channel. We experienced a raid earlier today.
If you wish to discuss the raid please do so in one of the off-topic channels.

potent quest
#

wow

#

some useful stuff got purged ๐Ÿ˜ข

#

noooo

#

@versed mortar we lost half of our conversation from yesterday

potent quest
#

๐Ÿ˜”

#

welp

proper wind
#

I got pinged?

versed mortar
potent quest
proper wind
#

mkay

sour lodge
#

Erm, this invite was previously pinned?

clever hornet
potent quest
#

I'm actually surprised the purge command doesn't avoid pins ๐Ÿค”

sour lodge
#

Right. Seems like something that should be pinned, so I'll do that.

sour lodge
#

Hello. Sorry if you were pinged in this channel. We experienced a raid earlier today.
If you wish to discuss the raid please do so in one of the off-topic channels.

We also lost a few messages from the last day as a result of the clean up, if you're wondering where they went.

wanton spoke
#

Why was my message deleted

#

nvm

pearl cliff
#

@wanton spoke you asked about pytest right?

wanton spoke
#

Yeah

worthy cairn
#

Why did I just get 3 pings here?

finite summit
pearl cliff
# wanton spoke Yeah

pros: less boilerplate code, more flexible test layout, nice command line with helpful printouts and lots of configuration options, powerful "fixtures" framework

cons: needs plugins to interact with certain other testing tools and doesn't always work with them

scarlet bluff
#

s

#

rajd?

jagged moth
wanton spoke
pearl cliff
#

overall for most new projects, especially personal projects, pytest is a good option

rose isle
#

crisis averted

wanton spoke
#

I've got a project that I've been working on for maybe two months now that I started with unittest and now I have about 105 tests

#

But pytest seems to have some features that would make testing easier and more effective

pearl cliff
#

it does, i think a lot of devs prefer it

wanton spoke
#

Hypothesis seems like a really awesome tool for testing.

#

I haven't started using it yet, but I think I'm going to start at some point

proper wind
#

What even happened

#

I got @ in here

pearl cliff
#

i love it @wanton spoke , i use it all the time

rocky sorrel
#

ghost ping?

proper wind
#

Think so

rocky sorrel
#

same here

pearl cliff
proper wind
#

Sick thanks for clearing it up

wanton spoke
storm pumice
balmy stone
#

nice poni

ruby estuary
#

Iโ€™m a huge fan of pytest. Itโ€™s easy to build it into pipelines

wanton spoke
ruby estuary
#

Yes

orchid crypt
#

Lmao this man typed out everyone's usernames to ping us all

copper summit
#

someone called me?

#

oh ghost pings?

native lava
fiery arrow
#

yeah, having a name start with a is dangerous ๐Ÿ™‚

honest zodiac
#

ping.

#

?

fiery arrow
#

(your name is early in the list, that's why you got pinged)

honest zodiac
#

oh

pastel crypt
#

starting with an a? dangerous??? (I got pinged 3 times)

pearl cliff
#

It's not always alphabetical

wise matrix
#

Why is pytest not scalable?

#

I can not run a single test without Pytest collecting all of them?

#

Whoever thought that's a great idea

pearl cliff
wise matrix
#

Pytest is not scalable, fundamentally

#

its a design decision

#

Pytest first collects data on everything, think of it has collecting meta which includes parameterizing, etc etc everything

#

whatever you want to do, run one test or thousand, it collects everything

#

and that's how they give all those wonderful fixtures

#

I have an expensive test setup process and simply can not afford to run all of those all the time.

#

because ram overflows during collection

#

The only solution to this problem is to comment out all other tests

pearl cliff
#

ah, i see

#

isn't that somewhat dependent on how the fixtures are defined?

wise matrix
mystic fjord
#

whats with the pings

rustic parcel
pearl cliff
potent quest
tight geyser
#

Couldnโ€™t you move the expensive test setup out of the collection process?

ember maple
# wise matrix Pytest is not scalable, fundamentally

there is a number of ways to avoid the pitfalls you created for yourself with pytest - a key reason why al ltests are colelcted first is that parameterization and setup cost test reordering needs to know all relevant items - a common solution it to simply run multiple pytest calls for parts of the directory tree if you have massive suites - also parameterization can be limited by configruation/options

#

there are some issues about memory use with >30000 tests- but those take time

pearl cliff
#

What would be an example of such a situation? A fixture that takes five minutes to run and loads 5 GB of data would run right at the beginning and unconditionally, rather than only "on demand" as with unittest?

barren bear
#

hmmmmm I could see that if one is using pytest to build a test suite for a database lemon_glass

sullen temple
#

What's a really good set of open source Python unit tests to learn from?

maiden pawn
#

I faced the same problem I have from time to time

#

trying different clients for testing django

client = test.Client()
api_client = APIClient()

resp = api_client.post(
        url,
        data=data,
        format="json",
    )

resp = client.get(url, data=data, content_type="application/json")
#

to make post request

#

but I get this
ValueError: Content-Type header is "text/html", not "application/json"

#

hmm, why the hell am I even getting this error

#

may be Nginx did not transfer headers

#

oh nvm

#

<HttpResponseNotFound status_code=404, "text/html">

#

that's why

maiden pawn
#

I need some command to run os system command from python

#

which returns return code

#
import subprocess
def runcommand(cmd):
    proc = subprocess.Popen(
        cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        shell=True,
        universal_newlines=True,
    )
    std_out, std_err = proc.communicate()
    print(std_out)
    print(std_err)
    return proc.returncode
#

nvm, works like a charm

hexed cloak
hexed cloak
#

It's checking for a lot of weird edge cases

maiden pawn
#

my stdout/stderr are shown in a real time now

hexed cloak
#

You'd use capture_output=True if you wanted to grab the stdout and stderr like you had in the code

#

The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases

maiden pawn
#

nah, I am good

#

it is working like I wished 100% now

buoyant wigeon
#

Habta hier laborrr?

maiden pawn
frosty crow
#

3 pings in here

analog breach
#

Hi, if I would like to unittest code with variables set by os.environ, can I set them same way in test.py? It seems like it would mess my system, according to what I found ๐Ÿค” Thanks

maiden pawn
#

though, I usually use those variables only in settings/config of my application

#

it looks a bit weird to me, applicating them directly into tests

#

it feels a bit wrong to me.

analog breach
# maiden pawn if you would use it only as os.environ.get("variable name"), I see nothing wrong...
    print(f"loading config from {fullpath_filename_config_yaml}")
    return yaml.load(open(fullpath_filename_config_yaml), Loader=yaml.SafeLoader)```
```        out_path = os.path.join(TMP_PATH, f"{s.name}.jks")
        with open(out_path, 'rb') as cert_f:
            new_cert = Secret(f"{s.name}-{format_to}",
                              s.namespace, SecretType(format_to))
            return create_secret(c, new_cert.build_jks(
                f"{s.name}-{format_to}", s.namespace, cert_f.read()), update=True)```
code works with files and there could be problem with running it running in threads to not overwrite these env vars.. So I would like to chceck them somehow ๐Ÿ™‚

is it okay to put `TMP_PATH = 'somepath'` in tests file if it's defined in main.py (in if __name/main block so not imported?)  I'm trying to validate. 
It feels like skipping a thing I should test also, if its right type ie. Can't wrapt my head around what right approach is..
daring sky
#

guys what do you mean by unit testing in python

#

i dont find any resources in pinned msgs Sorry found it in pinned msgs

#

ive heard these terms quite a few times but i really did not understand why and how to use it?? need help in this im going through the link provided in pinned msgs, seems like that has pretty much good info for me to get started

upbeat chasm
#

Hey. I recently bought Proxies from smartproxy and they got a traffic limit, so I want to minimize my traffic in Firefox. Is there a way to disable like image loading?

#
  • selenium
graceful sable
#

the pain of not having unit tests is quite high . I heard recently about unit tests to test new code ... seems essential . Looking into it right now , after hours of refactoring yesterday .. and then more hours following that "looking for where the issue stems from" . With a fairly abrupt interruption to everything breaking all at once in between ๐Ÿ˜…

#

tribute to named users here , we had a 15-20 minute discussion the other day in python general about unit testing with pytest and coverage.py

maiden pawn
# graceful sable the pain of not having unit tests is quite high . I heard recently about unit te...

https://www.manning.com/books/unit-testing
the book I recommend to all beginners

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.

#

Yeah. Industry level programming is impossible without unit testing

#

Unit testing speeds up programming by several times

#

and allows to not end up in dead end of not refactorazable code

graceful sable
#

I see ronny@pytest is here aswell , dropping wisdom . I'll probably scroll through previous messages

graceful sable
maiden pawn
#

pytest is good, that's what I am using

graceful sable
#

I will check it out .

maiden pawn
#

I am not just on this subject.
I am already acolyte of TDD cult)

graceful sable
#

i see ... ```TDD is a part of agile development where developers write code only when a test fails. A programmer writes a test first, even for the smallest of functionality and runs it to get an obvious fail. Then the programmer writes code only to satisfy the test.

#

thats where i plan to be ! ๐Ÿ˜„

#

i want to be that when i grow up

maiden pawn
#

a little bit weird description

graceful sable
#

man it's been a frustrating past 12 hours fixing all this code . Its so organized when its written and then stuff breaks and its all a mess

#

look forward to unit testing

maiden pawn
#

yup.
Writing tests brings you assurance, that your code works

#

makes you really fast to identify problems

#

and. well... you wil start writing code that can be easily tested

#

which sort of restructurizes your code work into much better one

graceful sable
#

It's very nice . I haven't picked up the subject from only an interest

graceful sable
maiden pawn
#

refactoring without unit testing = week / weeks of time
refactoring with unit testing = day / days at best)

#

speeds up bringing new features as well

graceful sable
#

And saw that the code was using .. the "assuming feature, as i call it" basically where you describe in a function which type you are expecting to get input into a function , and then you can run a test on whether you're getting the types you're expecting .

#

That was a conversation that i didn't hear was explicitly about unit testing

#

moreso about preparing packages for large distribution. pypi

#

i forget what the technical term is

#

assert type of variable

maiden pawn
graceful sable
#

I'll get into this book , and unit testing . Wont be uninformed while talking about it for long ๐Ÿ˜„

maiden pawn
graceful sable
#

yessir

maiden pawn
#

just kidding.

#

but it sort of shows the possible maniac-ism in this direction)

graceful sable
#

do you have code on github that has unittesting that i can reference? @maiden pawn

graceful sable
iron slate
#

HAHAH lol

maiden pawn
#

Regretfully, not a lot of time left for public projects at the moment.

#

Too much needs to be learn in free time

#

Like.. I am having too many gaps in other important fields. Which I can't afford having due to current position.

graceful sable
round blade
#

The reason it is helpful in your case is because when refactoring code you want certain behaviors to hold constant. Enshrine those behaviors in tests prior to making changes.

#

TDD is not always correct. It is however correct to have unit-tests prior to doing refactors.

graceful sable
# round blade TDD is not always correct. It is however correct to have unit-tests prior to doi...

ive heard it does take longer to write initially. (and while looking into it more, it's obvious that it does) . I have been writing tests with most of my code already, just havent been utilizing "TDD" to do so . the libraries and so forth. Difficult to make a function that can be extracted to a second test file to run just that piece of code, when it depends on other parts of the program . I see TDD libraries support better ways of doing so

#

the projects are large , more than 50-100 lines (for a reference) ... and with the plan to add more / learn things in the process .

graceful sable
#

thats how i plan to use it when having an existing project already

#

usually watch a couple videos from youtube where im familiar with how the developer structures their information . in this case , Corey (Schafer, https://www.youtube.com/watch?v=6tNS--WetLI ) and Socratica (https://www.youtube.com/watch?v=1Lfv5tUGsn8) . Usually when its a long video just clicking through it to see the progression and snippits.
i follow a bunch of others on youtube but i see they havent made a video about this . Could probably do better to search each channel for a relevant video though .

round blade
#

Some people stick a tests folder inside the package, other people do it inside the root repo. "When extracting a function to a separate file" I am not sure what you mean (just importing?) and what relevance it has for the tests, but tests should import from your code. I highly recommend pytest over unittest

round blade
graceful sable
round blade
#

You should probably look into how a good python project is structured, especially if you are struggling with things like importing functions across files. Try to look at the source code for a library you're familiar with and try to understand its structure and how things are made available across files

#

Like "this function was defined in file A and it's being in file B-- how?" etc., then see how that's done in the tests as well.

graceful sable
#

becomes more and more blocking ๐Ÿ˜„

round blade
#

I think the code will be a bit easier to reason about if you leave your __init__.py's blank. (Sometimes you stick stuff in there, but often easier to reason about it when it's blank). Just use the __init__.py to indicate that you intend to make the modules and their objects importable.

#

If you have a folder called foo with an __init__.py, a.py, and b.py, you can import a function called bar, defined inside of a.py, into b.py, by writing from .a import bar.

#

^ When you write and run your tests however, you may or may not (depending on how you set things up) have the tests inside of the foo/ folder. It might be inside a separate tests/ folder. In a file tests/test_something.py, you would import the test with from foo.a import bar.

#

Note-- you can also run from foo.a import bar inside b.py. The absolute path works in both cases. The thing that matters is where your terminal is pointing to when you run the code. from foo.a ... is an absolute import, from .a ... is relative.

#

it's just that within the package, you get the choice of absolute vs relative. If you define tests outside of some package you need to do absolute.

#

this should help you understand how to bring bits and chunks of code into your tests, regardless of wherever you define the tests.

graceful sable
#

the issue with running tests , even with an import is that some of the functions i aim to test depend on other objects to have been instanced .
I haven't seen whether unittesting has a solution 100% , i am supposing it does in the integration. (which fixes the problem)

and the issue that has lead to moving the instances to the __init__.py file is that i've seen the instances declared in the __init__.py file are accessible to all other modules , which is what i need . Especially while using sql alchemy sessions i see it's recommended to run this is a main file .. which i see could be the executing file or simply the __init__.py file . I see the init file is not usually referenced this way though

#

having an issue where a class needs access to another class that is instanced in a different file , without having a sloppy import .. or what i see is weirdly referencing the instance while instancing the class that needs to use it in another file .

#

It's a rabbit hole that im looking to avoid

#

@round blade

round blade
#

the issue with running tests , even with an import is that some of the functions i aim to test depend on other objects to have been instanced .

It's possible that this is a problem with your code relying on mutable global state.

graceful sable
#

And there are other things i see to refactor.. like the structure of having things in folders

round blade
#

basically your functions should "just work"

#

if there are things that need to be set up prior to running tests however, use "fixtures"

graceful sable
#

in this file you can see at line 208 that it references to an instance of db. for example . py def update(self): '''update stream statuses''' # get the current stream queue queue = db.get_operator.queue() # retrieve current status of each stream for i in queue: # if the stream is live var = status(i) if var == True: status_queue.append(i,var) # pass streams to db manager print(status_queue) db.set_operator.status(status_queue) which calls a class inside the database.py file that was instanced in app.py
https://github.com/swordysrepo/api_twitch_online/blob/staging/API_function.py

#

these 3 files "need to be available" to each other file .. and the classes are initialized

#

in this case py print(status_queue)
is something i plan to comment out later . It's a "test" to see what the value is while passing it along

#

sometimes lose track of where the print statements are , so i made a function , in debugging.py for optional print statements. basically when debugging == True then the messages print .

#
import sys
class checkAlert:
    def __init__(self):
        self.debug=False
    
    # def alert():
    #     currentline=
    #     print(currentline)
    # def check(self,msg = None):
    #     print(f"check/debug {sys._getframe().f_back.f_lineno}: {msg if msg is not None else ''}")
    def check(self,msg = None):#this sends when debug is enabled 
        if self.debug==True:
          print(f"check/debug {sys._getframe().f_back.f_lineno}: {msg if msg is not None else ''}")
    def check1(msg = None): #this sends whether debug is enabled or not
            print(f"check/debug {sys._getframe().f_back.f_lineno}: {msg if msg is not None else ''}")



check = checkAlert()
check.debug = True``` https://github.com/swordysrepo/api_twitch_online/blob/staging/debugging.py
#

also prints the line that the message is on . So can use it even as check.check() and it will show which line "the program got to" . It's a pypi package i posted .. i forget what the name is .. and whether the install is properly working . And also on github

round blade
#

my advice is-- create a string called SQLALCHEMY_DATABASE_URI. Then do something like this:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
#

Then whenever you need to create a new session, simply do db = SessionLocal()

#

you have a little more flexibility, in particular this implementation does session pooling and you might want to create some sort of way to close out of sessions when you're done with them.

graceful sable
round blade
#

but even just doing db = SessionLocal() inside the file at the topmost level indent is going to be better than what you're currently doing IMO.

round blade
# graceful sable further looking into fixtures, it does sound like what i am looking for , when r...

yeah so then the next step if you take my code would be to do something like this:

# contents of tests/conftest.py

import pytest
from foo import SessionLocal

@pytest.fixture
def db():
    db = SessionLocal()
    yield db

^ this works to create new sessions for each tests. then when you write a test to make it available you add db into the function signature definition (pytest is weird, it's very metaprogrammey and magical-- but tldr it knows to use db if it's defined in there.)

#

but in order for that to work you need to make sure your code is built to take in the db objects in the right spots.

graceful sable
graceful sable
round blade
#

ignore what I said about SessionLocal etc

#

use Flask-SQLAlchemy

graceful sable
# round blade use `Flask-SQLAlchemy`

interesting .. I heard that it doesn't offer much that would make it worth learning outside of regular sql alchemy , and so i haven't integrated it . and learned each seperately together . To be able to use sql alchemy exactly the same in other projects

round blade
#

Flask-SQLAlchemy uses a globally defined object called db that does all the session management for you. You do not need to implement it the way you did. Simply have this inside of a file:

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
graceful sable
#

i have a sample of code that uses flask alchemy that i considered using .. one sec

round blade
#

Flask-SQLAlchemy is mostly the same as regular SQLAlchemy.

#

but it does a few things-- it uses the Flask config, it is extendible with things like Flask-Migrate, and most conveniently-- and what's tripping you up btw-- it has its own session management

graceful sable
round blade
#

^ yeah something like that.

graceful sable
round blade
#

also, the fact that Flask-SQLAlchemy is extendible matters. for pytest there's an extension that works specifically with it that is, IMO, a godsend of a module.

graceful sable
#

yeahhh , i'll take a better look at it

round blade
#

to the extent that I can't imagine connecting to a SQL database in a Flask app any other way. It's just the way you're supposed to do it basically.

graceful sable
round blade
#

session management in base SQLAlchemy is mildly annoying-- by that I mean, it's a solved problem and you can copy+paste code, but it's annoying that you need to copy+paste code.

graceful sable
#

started with mysql calls .. adn the added postgres with psycong2 .. still kinda crude method of communicating with databases. then added sql alchemy .. see it's time for the flask extension and pytest. Can see the progressions through the commits

round blade
#

Flask-SQLAlchemy solves the problem very nicely by integrating with a few Flask internals involving request contexts.

graceful sable
#

"too much" copy pasting without sql alchemy imo

round blade
#

are you using mysql or postgres? you have sqlite!

graceful sable
#

postgres

round blade
#

oh I see what you're saying

graceful sable