#unit-testing

1 messages ยท Page 6 of 1

limpid perch
#

That is not the folder structure though, please read again above ๐Ÿ˜‰

pearl cliff
#

that is: python modules do not necessarily correspond to filesystem directories, and the correspondence depends a lot on how python is configured to search for modules

#

loosely speaking, python looks for module xyz in either xyz.py or xyz/__init__.py somewhere at the top level in one of its search locations. it looks for module xyz.abc by first finding xyz as above, and then finding abc inside xyz using the same logic.

limpid perch
#

Just started using python so for me it is just folders

pearl cliff
#

so for python to find xyz.abc, you need xyz/__init__.py and xyz/abc.py , where xyz is at the top level in one of the search locations

limpid perch
#

Yeah I have a few of those init files so slowly learning how it all works

pearl cliff
#

well, it's documented, but it's all very technical

limpid perch
#

Agree! Have spent quite some time on it already and it is not crystal clear as other laanguages

pearl cliff
#

does my explanation about xyz make sense? lua actually works very similarly, if you're familiar with lua

limpid perch
#

Yeah it makes sense

pearl cliff
#

let's say the python search path is (simplified and not realistic) ['/usr/lib/python3.10/site-packages'], then when you run import xyz , python will only look for /usr/lib/python3.10/site-packages/xyz.py or /usr/lib/python3.10/site-packages/xyz/__init__.py and nothing else at all, nowhere else

#

(in practice modules can be in zipped files, compiled shared objects, and other exotic formats. it's fully customizable if you have some specific needs.)

limpid perch
#

Good to know!
My next mission to figure out is then how to properly test fastapi routes, right now I just added a assert response code == 200 which is not much of a test really

pearl cliff
#

that's a good start but that's a whole separate discussion ๐Ÿ™‚

limpid perch
#

And also how to switch the db from MySQL to nosql

pearl cliff
#

And also how to switch the db from MySQL to nosql
why? i'd strongly recommend against this

#

especially for what looks to be a relatively beginner-level project

#

what nosql did you have in mind? mongodb?

limpid perch
#

Better to setup a db relica?

#

Sqllite

pearl cliff
#

what purpose do you have in mind?

#

sqlite is very much not nosql!

limpid perch
#

Yeah my bad

pearl cliff
#

sqlite is sql, it's in the name ๐Ÿ˜†

limpid perch
#

Was going to say sqllite but yeah tired hehe

pearl cliff
#

but yes you should definitely use the same database in test and prod. ideally you'd run a local mysql instance and populate it with fake data, or a subset of real prod data (but you want to be very careful about things like user PII and other sensitive info)

proud nebula
limpid perch
#

But I would prefer not to do inserts in the live db though

#

Thatโ€™s why I am thinking testing should be using something other than the live db

pearl cliff
#

no of course not. you'd run a local database and only use it for testing

proud nebula
pearl cliff
#

yeah, i meant that if your app uses mysql, you should run your tests with mysql

limpid perch
#

Ah yes

pearl cliff
#

so you'd run tests by first starting a local instance of mysql, then running the test suite with env vars and config files set as needed so it talks to the local instance

limpid perch
#

True! That is what I did start before leaving the office so should be good on that one then

proud nebula
#

or you run tests with different settings so it goes to a separate "db" or "schema" or whatever it's called in your db of choice

#

starting/stopping is a bit excessive imo

limpid perch
#

What should you test except status code 200 (or another) on the fastapi endpoints?

proud nebula
limpid perch
#

Use the pydantic models and test the response vs those?

#

Snapshot testing?

proud nebula
#

yea, you basically hit the endpoint, store the response and check that. But in an automated way. So if the response changes you are alerted and you can decide that you want the change or it's a mistake.

limpid perch
#

So then not really use the pydantic model as that will be updated if the endpoint is updated? The test would then not really ever fail-ish

#

I come from 15 years of classic asp and have never used tests for anything so forgive me if my questions are not great, still slightly struggling with understanding the benefits of the tests

#

I get it if the project grows really. If and you have hundreds of endpoints and change something in 2 years from now and the test will find the issue before anything goes live

#

But when working on this 100% right now errors are found during development

proud nebula
#

Lots of bang for the buck.

#

Tests are a HUGE topic. There's unit testing, end-to-end testing, test driven development, mutation testing (I'm the developer behind mutmut :P ), property based testing, fuzz testing.. probably 10 more I forgot

limpid perch
#

So a test should fail if you modify your code, even if the actual code works?

proud nebula
#

Each has its place. You need to learn what is useful where. There is nothing that is always good.

proud nebula
limpid perch
#

My thought is that I modify something in a year from now somewhere in code base and then forgot to change something else which my tests will catch = prevent an issue from ever going to prod

#

If I get that, I am happy

proud nebula
#

Yea, that's the ideal

dreamy bough
#

@limpid perch When you write unit tests โ€ฆ youโ€™re trying to test all the possible execution paths (the expected return values from the methods). In Unit tests, you do that using the โ€œArrangeโ€, โ€œActโ€ and โ€œAssertโ€ or AAA. The โ€œAssertโ€ part is where you verify if your production code works by manually providing your test case with expected values. A test can fail if you provide the wrong expected value or modify your production code to return different values.

pearl cliff
#

are there any books that specifically talk about testing of "data processing" code as is often seen in data science and machine learning? not necessarily numerical algorithms, more like data cleaning and implementing business logic in libraries like pandas or even sql.

jolly tangle
#

I have a question here. I have my doubts it will be answered on stackoverflow Does anyone know the answer? https://stackoverflow.com/questions/77305031/how-would-i-pytest-a-flask-wtforms-custom-validator

The question is How would I pytest a flask wtforms custom validator?

maiden pawn
#

flask forms are basically rendered on current url on GET, and accepting info on POST

#

u could just create unit test that inputs your correct and incorrect password and sends to your url with POST request (u could open browser tab with networking and check exact path/params etc stuff)

#

then u will not need to know about internal flask details how it works

#

Of course there is always wish to have it more unit testful ๐Ÿค” in that case good luck in figuring out flask internals ๐Ÿ˜…
Or just use optionally mocks to imitate them

#

pass your own data structures in form and fields variables, no point to send real flask objects

jolly tangle
#

@maiden pawn
I am just going to state I am confused what to exactly do. Would something like this work?
Checking the code on the brower might be a good idea ignore below till I try that.

https://testdriven.io/blog/flask-pytest/sends

from project import create_app


def test_home_page_post_get():
    """
    GIVEN a Flask application configured for testing
    WHEN the '/' page is requested (GET)
    THEN check that the response is valid
    """
    # Set the Testing configuration prior to creating the Flask application
    os.environ['CONFIG_TYPE'] = 'config.TestingConfig'
    flask_app = create_app()

    # Create a test client using the Flask application configured for testing
    with flask_app.test_client() as test_client:
        response = test_client.get('/')
        assert response.status_code == 200
        assert b"Welcome to the" in response.data
        password = 'some password'
        return password_form
def test_home_page_post(test_home_page_post_get):
    """
    GIVEN a Flask application configured for testing
    WHEN the '/' page is requested (POST)
    THEN check that the response is valid
    """
    # Set the Testing configuration prior to creating the Flask application
    os.environ['CONFIG_TYPE'] = 'config.TestingConfig'
    flask_app = create_app()

    # Create a test client using the Flask application configured for testing
    with flask_app.test_client() as test_client:
        response = test_client.get('/')
        assert response.status_code == 200
        form = login_form() 
        field = test_home_page_post_get()
        with pytest.raises(ValidationError):
               make_password_contain_capital(form, field)
        
maiden pawn
#

oh yeah, u already use it in your code

jolly tangle
#

Thanks

For some reason the assert assert b"This text doesn't exist" in response.data is coming back true even though the text doesn't exist anywhere in the html? Also 300 also comes back as true even though I want a 200

def test_register_page_post(client):

    with app.test_request_context():    
        response = client.post('/register', data = {'username':'zzz', 'password':'rrrrrrrrrrrrrrr' })
        assert b"This text doesn't exist" in response.data
        assert response.status_code == 300
jolly tangle
#

thanks for all the help. I found a video that covers my question I am going to try that

ember maple
#

anyone aware if thees any observability libs for python that combine pythonic api (like eliot), local reporters for test assertions and opentelemetry integration

fervent sky
#

Is there some book or guide to sort of "train" my mind to know what to unit test and what to not? My modules are not very independent, and I am finding it hard to find something to unit test. I can probably make them more independent given time, but I kind of feel like it doesn't need unit testing at all, but that thought is no easy to bear either.

PS: I have never done unit testing before.

fervent sky
#

I found some resources on Reddit. I will go through them. THanks.

limpid perch
#
    response = client.get("/alley/1")
    assert response.status_code == 200``` How do I convert the response to the pydantic model it actually returns?
maiden pawn
#

This book explains what you should test and what you should not, what to aim for

#

to undertand it fully requires some additional books and technologies though.

#

this book is good foundation to give... 50%+ unit testing understanding at minimum

fervent sky
#

I see. Thanks for the reference. I also found the Art of Unit Testing's third edition which is written with JS snippets and I think that one will go well too.

#

I will check with one out as well

maiden pawn
# fervent sky I see. Thanks for the reference. I also found the Art of Unit Testing's third ed...

you can scrap additional 50% of understanding if u will read

  • TDD by kent beck, this one teaches feeling at practical level how often unit testing should be done. What is step between writing working code and tests
  • Clean Architecture by Robert Martin, this is a book giving understanding into manipulation code architecture of your application at a global scale. It gives understanding how to structure your code for more unit testability as side result
  • You need to learn static typing in strict mode with mypy preferably and using pydantic. / optionally learning static typing from real static typed languages like Golang to get it easier. It gives understanding that there is no point to test anything related to types and DTO carriers, and it gives foundation to structure your code in a real clean architecture way, that makes easier room to make architecture more unit testable further
#

may be there is more stuff to know... but that's where my knowledge about unit testing ends ๐Ÿ˜…

fervent sky
maiden pawn
#

really awesome data carrieng structs with it

#

with runtime type validation a bit

#

it complients static typing greatly

#
  • good tool for generic settings input into app
maiden pawn
fervent sky
#

I have mostly done my validation stuff with dataclasses, but I'll check that out as well.

fervent sky
#

do you recommend any lang? I am thinking of Kotlin

maiden pawn
#

Kotlin should work okay too. if that what fancies you

#

i try to get into Java/Kotlin too, but personally finding that Golang has smallest learning curve and most dev comfort

fervent sky
#

Golang seemed a little too comforting, so i"m more leaning for Kotlin

#

they have enums and dataclass all natively with nice syntax, not sure about golang

#

even abstract classes have distinct syntax

#

i got to import all this stuff when it comes to Python, which is kinda tiresome

maiden pawn
sleek python
#

I am working on a flask app for work as a side project, and I am working out the CICD process and figured I should add some unit-testing to the process as well...I know, cart before the horse. Anyway, the webapp is heavily database driven with not much in the way of any logic being accomplished. The webapp is being written to replace an Access database, and pretty much all of the basic functions have been replicated. Along with working out the CICD and unit-testing process, I also have some requested updates to add. I have not written any code that utilized any unit-testing prior to this at all. I have at least worked out that basic routes are being validated but that is about it. Pretty much every other route pulls data from the database to edit or delete records or adds records to the database. My local development environment utilizes a postgresql database as will the production application. I have scoured the Internet for pointers on utilizing unit-tests but none of them seem to fit...but, I may just be missing something. Any help appreciated, thanks!

proud nebula
maiden pawn
# sleek python I am working on a flask app for work as a side project, and I am working out the...
  • Consider to ensure also having database migrating code
  • good combo to utilize Pytest + factory boy for db unit testing purposes. Helps to write shortest code that matters.
  • run migrations only once, wipe tables between tests
  • use docker/compose locally to have db present of correct engine to run.
  • use stuff like GitHub actions container services to make it available inside CI too (or u can reuse compose)
dreamy bough
#

How do you implement integration test? Or Is using fake backend with something like โ€œโ€https://www.mockaroo.com be implementing an integration test? I understand the theory of integration test, but not the implementing in code.
Letโ€™s say I have a class called โ€œVideoServiceโ€ thatโ€™s connected to a โ€œFile.txtโ€. Will creating a โ€œFake Objectโ€ within the โ€œVideoServiceโ€ class and using it instead of the actual โ€œFile.txtโ€ be performing an Integration Test? Thanks!

maiden pawn
#

General testing in robot would be too awkward though. Nasty system without debugging

#

I don't like it

#

I would prefer seeing integration testing done in Pytest too

#

Going to go this way for my maintained library

dreamy bough
#

@maiden pawn Thanks for letting me know. Why not use "Pytest" for db ?

maiden pawn
#

pytest is fixture and feature rich testing framework with most comfort

#

I can only look sad from other languages that don't have stuff as nice as pytest

dreamy bough
#

@maiden pawn I read "unit test" which I think is another testing lib. That's why I asked.

maiden pawn
# dreamy bough <@370435997974134785> I read "unit test" which I think is another testing lib. T...

I tend to have not very strict definition for unit testing.

As long as testing is done in same language as main application code, tests have access to mock if necessary any parameters in sub code and don't invoke any uncontrollable third party dependencies, it is still unit test to me.
Database is locally raisable comfortable dependency that makes up more than half of app logic. No point to consider it being not part of unit tests for me for backend applications

proud nebula
#

Some say "unit tests" is only in-memory and no db (even though sqlite :memory: can be in-memory and in-process! yea, it makes little sense)

sleek python
# maiden pawn - Consider to ensure also having database migrating code - good combo to utilize...
  • I definitely wanted to include db testing as part of the process. I wrote a test that kinda worked, but it was using my active development database. So something obviously isn't right.
  • Can you point me to a good pytest + factory boy example?
  • Would it be better if I use a pgsql container for dev work instead a full blown pgsql VM? Would I use the same for CICD testing?
  • I would assume that using respective gitlab services would do the same thing?
sleek python
proud nebula
proud nebula
#

regression testing is to not make the same mistake twice

maiden pawn
# sleek python - I definitely wanted to include db testing as part of the process. I wrote a t...

i use mostly pytest-django philosophy in any application.
I can provide test example in golang application if u wish.

anyway, the point is.. we create a test database to which we apply migrations
and we create only once for all tests

Then we write unit tests that use Factory boy to create quickly SQL table records
then run our endpoint code, or code wrapped into some lib, whatever
then we assert that we got expected result, expected json, or amount of records/values in sql tables.

optionally with pytest-django we also utilize how many sql requests we made ๐Ÿ˜… pure Django ORM problem

#

So...

  1. in any application i create fixture that creates db with all applied migrations one time
  2. then in specific objects i create sql records
  3. run records
  4. wipe tables between tests
proud nebula
#

Personally I turn off running migrations on my django projects. It's WAY faster and I just don't have migration issues basically.

maiden pawn
#

in my golang app code i needed to fill db only one time though... because i was testing performance it was fine to me to fill db only once ๐Ÿค”

#

easy to do with pytest, just changing scope to session

sleek python
#

@proud nebula @maiden pawn So basically my process has been to have the flask app running "live" in "debug mode" then edit code until it does what I want. Is that the "wrong way"?

maiden pawn
#

u will be able to call flask endpoints and edit(mock) its code on runtime then if necessary
i think test_client does not require running flask for interations with it

proud nebula
#

Don't be religious about this stuff. Think for yourself, try to see what works for you and your situation.

maiden pawn
#

developed whole libraries, without realizing i forgot to test if it is actually able to run in live mode

sleek python
#

I think part of my problem with the unit testing is that since I was writing the app while it was "life" and debugging on the fly I am not sure what to actually do unit testing on.

maiden pawn
#

when you hook debug to pytest test, u are able to write test in edit mode pretty much too

#

difference that we localized scope of affected code
and made replicable environment for specific code to test

sleek python
#

pretty much all of my functions query the database for data, do something with the data and rewrite if needed

#

I write my code in sublime text and have he app running in another terminal so I can se the debug output

#

I also have the app open in a browser to test my changes to see if the app does what I want

maiden pawn
# sleek python I write my code in sublime text and have he app running in another terminal so I...

I could recommend reading

  • Unit testing best practices by Khorikov, for theory behind and what to aim for, why important, what should be tested and what should be not. What to avoid for in order to not get dessapointed
  • And TDD by Kent Beck, for head on practical example how to do, and to learn feeling how much u can write working code between need for tests (it makes controllable step of made risk between saving points in this game)

They can help reach right mentality.

sleek python
#

I learned python flask/django development from courses on Udemy and that is how it was generally demonstrated...but there was NO unit testing at all

maiden pawn
# sleek python I learned python flask/django development from courses on Udemy and that is how ...

Unit testing is average technique of a higher grade developer. Strong juniors and just all Middle developers in industry do it.

It is common for people with less skill than strong juniors to never do that ๐Ÿ˜‰ (for example common for all student level people never do it, or just people which do programming as hobby only)

Yet it is important part of making maintainable code for long term, that is easier to extend in new features. Which is why it is done all the time in companies with real software developers

sleek python
#

fair enough ๐Ÿ˜‰ I am a Linux Admin by trade, but I enjoy working with python. Which is how this project and a couple others of similar nature ended up in my todo list. I don't mind, but obviously I am not a "strong junior" python dev yet :D.

#

I prefer doing things the right way which is why I started down the unit testing path in the first place. Since it is just an internal application for a few users...is my development process sufficient for the task(s)?

proud nebula
proud nebula
maiden pawn
#

Hehe, ๐Ÿ˜… now u are attempted being subjugated to another cult

#

That has little amount of people that tend to share idea how it works

sleek python
#

Alright, is the way I am doing it, the "wrong way"? I definitely understand trade-offs between current method and proper unit testing, even if I don't know exactly how those "trade-offs" would look or function like exactly. I don't see myself being a full blown python developer as I am too close to the end of my career to change, but I definitely fit the "hobbiest" label

#

IT is full of cults, that much is for sure along with niche's within cults!

maiden pawn
proud nebula
#

I think Darkwind is a bit fanatic about static typing heh

maiden pawn
#

๐Ÿ˜› I am for stuff that makes things more maintainable and rapidly refactorable.
As well as having ability to organize custom code to have better connections(loose coupling, right cohesion stuff)
Static typing is heavily boosting those parameters

proud nebula
#

It's all about CONTEXT.

  • How critical is it if something fails?
  • How easy/fast is it to fix it?
  • How much time do you spend doing static typing?
  • How much time to do you spend on chasing coverage?

There's tradeoffs everywhere

#

If I shipped something to Mars I would be super paranoid about static typing. When writing a hobby project I might not do any static typing and no unit tests.

maiden pawn
#

I prefer to write my pet projects with mind I am going to maintain them for years. (And even extend in features later)
And that I will forget everything about it in some year pause.
Plus I tend to make pet projects showable at resume

If it is throw away script, I am not going to maintain (or show at resume). I am fine not typing or testing it

proud nebula
#

I'm a 22 year veteran, I don't need to care about my resume :P

sleek python
proud nebula
maiden pawn
proud nebula
#

Good naming is basically typing for most uses anyway

maiden pawn
# proud nebula I don't think typing helps that much

Yet it does. Makes way more readable and extendable. Without need to remember all magic attributes, methods and values your code could be having or not having at certain point of time at runtime

It helps to make code localized, to when u need to read only small part of it to understand fully. (Because all possible input and output is strictly defined)

proud nebula
#

Very different things.

maiden pawn
#

Typing helps to write better code architecture

proud nebula
sleek python
proud nebula
#

especially not in python where objects are mutable by default and passed by reference

proud nebula
#

Typing is one thing. Pure functions is another. Totally separate.

sleek python
#

thanks to both of you for the help, it was very much appreciated

maiden pawn
# proud nebula especially not in python where objects are mutable by default and passed by refe...

Typing helps to define explicit allowed mutations to all objects
Defining strict structs of allowed values, including if they can be or can be not None
Typing helps to define explicitely which methods should be present at specific object in a certain code part.

It makes strictly defined borders of object mutability.
Which is achievable as long as it is your code that controles those objects. If you took under your own control third party lib objects and wrapped them into isolational layers.

#

Immutability is achievable, making predictable all input and outputs possible to specific code parts

#

makes possible to write code easily acconting for all possible value types that will be present in specific object

#

Strictness borns perfection.

#

without this striction, yeah, you are dealing with mutable Any that can be having attributes and methods of multiple Any... then you would have a trouble

proud nebula
#

Yea, you just wrote a lot of stuff unrelated to the point.

sleek python
#

its like a train wreck that I can't stop reading...hehehehe

proud nebula
#

You can write pure functions with 100% dynamic typing.

#

I mean, that's just trivially true.

maiden pawn
#

ergh, but it will not be having a very solid guarantee it accounted for all edge cases your code needs
or that it is called and having its return correctly across all app code.

#

typing helps to refactor code rapidly for any stuff

#

because your IDE/mypy/pyright highlight within 1 second shows all places you need to correct code to its new input/outputs

#

more rapid feedback to refactor code... is exactly why it is awesome.

#

rapid instantenous feedback for a lot of code correctness.

#

quite often possible making changes to code that will work correctly even if u did not run it, or did not launch unit tests

#

(which is pretty much impossible endavour in fully dynamic typed code)

proud nebula
proud nebula
maiden pawn
#

if guarantee is broken, then it is only your own fault you need to fix and achieve back

maiden pawn
#

typing helps heavily to have this Refactor Driven Development going ๐Ÿ˜Š

#

typing is part of testing pretty much, that accounts for edge cases, people just should not unit test but type instead

proud nebula
#

Dude, just admit you said something weird and let it go.

#
def foo():
    return 1

this is pure. No static typing can change this.

maiden pawn
#

it is

def foo() -> Any:
  return 1

that by pure accident returns integer constant only.
Not guaranteed to work correctly across your code because other code parts can be treating it with assumption it can be returning string or smth else
Because u just did not define correctly contract what your pure function can do for other code parts

proud nebula
#

I see.. you don't know what "pure function" means

#

aaanyway

maiden pawn
#

i understand that you mean pure as stuff without side effects, but that is the thing.
I think your code cant be pure unless you defined strictly what it does, that other code parts can comprehend

#

whatever

proud nebula
maiden pawn
#

it is important defining explicit contract how your code part works

proud nebula
#

Just admit when you're wrong. Ego destruction is good.

maiden pawn
#

i still see no where i am wrong
Within my mentality / structure how to approach things... i still said stuff correctly. ๐Ÿ˜›
no defined contract = code can be doing anything, including returning by accident file stream to read file, instead of Literal[1] you expected to receive.

#

and than bigger code of function, then more different returns it has, then more chaotic dynamic typing stuff becomes

proud nebula
maiden pawn
#

hard to do with third party lib objects, but more or less easy to do in controlled your own code that is fully strictly typed, and isolated dangerous uncontrollable super mutable untyped stuff away

proud nebula
maiden pawn
proud nebula
#

You really need to brush up on your theory

maiden pawn
# proud nebula How does typing do anything to stop this function from having a side effect: ```...

So, side effect for you lack of this function deterministicity, because it relies onto global seed to output different random values?

Sorry, but I need to understand first what is your definition of side effect first. Side effect for me is affecting global state as result of function execution, but this function is not affecting it. So it has no side effects by my definition. Therefore you have a different definition of what side effect is, therefore I need to identify requirements better before taking further actions

proud nebula
# maiden pawn So, side effect for you lack of this function deterministicity, because it relie...

In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, which is to say if it has any observable effect other than its primary effect of returning a value to the invoker of the operation. Example side effects include modifying a non-local v...

#

It's not MY definition. This is basic computer science terms.

#

I'm gonna guess you didn't go to university for this...

#

Hell, I'm a university drop out and I know this stuff

maiden pawn
proud nebula
#

oh dear, that article is wrong.hah

#

Example side effects include modifying a non-local variable, modifying a static local variable, modifying a mutable argument passed by reference, performing I/O or calling other functions with side-effects

#

performing I/O

#

random stuff is defined as IO in Haskell for a reason

#

Anyway, randint WILL mutate global state

#

You can tell because if you call it twice you get different results.

#
def foo():
    return randint(1, 5)

Please add typing until the type checker complains. I'll wait.

#

I'm still waiting

#

(ok, the article isn't WRONG, just.. not as helpful as it could be)

maiden pawn
#

No, it just reads different states of global as an input

But it is not changing it... (Unless u speak about pseudocode random generators, that under the hood change their value only when they are invoked)
But here is the trick... For our code in general it is illusion, that it is actually real random global input (therefore having no side effects).

Anyway, i understood what is that you wish.
Your randint is pseudocode generating function to you and therefore is having side effects.
That makes propagated side effecting into foo function for you

proud nebula
#

otherwise it would always return the same number

#

think about it

maiden pawn
#

it is reading global state that is supposedly random.
it is not writing some new state to anything global
it just accepts global input value as current input.

proud nebula
#

duuuuude, THINK

#

If it did not mutate global state then randint() would return THE SAME number

#

ALWAYS

#

How does it know to go to the next number?

maiden pawn
#

And here we finally achieved coming to core of your mentality / construct that makes your philosophy

proud nebula
#

lol

#

My mentality doesn't change bits in RAM dude

maiden pawn
#
def foo() -> int
  seed = current_seed_at_global_state()
  rand = random.init(seed)
  return rand.int(1,5)

in any case it is still not changing global state, it just reads it as input

if you wish achieving purity and happiness within your own philosophy, just add seed as part of input

def foo(seed: int) -> int
  rand = random.init(seed)
  return rand.int(1,5)
proud nebula
#

so now you have TWO calls to mutate global state

#

congrats

#

still waiting for your static typing to guarantee purity

maiden pawn
#

static typing does not guarantee purity.
But it helps to promote it, by eliminating a lot of possible side effects affecting input/output in different ways to code part

#

i did not tell that it guarantees to reach purity ๐Ÿ˜‰

proud nebula
#

oh, and the code you wrote above crashes lol

proud nebula
maiden pawn
# proud nebula The last step of losing an argument: deny everything

๐Ÿ˜› achieving anything in absolute 100% is very often having high cost.
achieving 100% unit testing coverage
achieving 100% typing
achieving 100% uptime and 0% downtime (requires infinity money pretty much)

I am person that is happy with something between 80 to 99% percentages of stuff (i tend to like number around 95% though)

#

that is stuff that is
part of SRE book
part of Unit testing best principles by Khorikov

river pilot
maiden pawn
# river pilot that essay doesn't seem to mention typing? I'm also missing the connection betw...

Static typing (strict one in mypy/pyright) helps to define explicit contract what is code able to process and what to output.
It prevents you from breaking this defined contract

What is pure function?

  • thing that for input X, returns explicitly Y
  • and also having no side effects.

Typing allows to restrict function working with those X and Y types only and handling all edge cases to different its possible values.

Side effects aren't directly affected by static typing, but explicit defined contacts how your code works helps to refactor quicker code to better shape. (Including easier to refactor to make code part pure if wishing, just a matter often enough to lock info static method decorator, to turn smith stateful in often enough pure)

river pilot
#

I agree that static typing can make it easier to understand code, and help with refactoring. it just doesn't prevent you from having side effects. It's a separate consideration.

maiden pawn
#

Sure it does not

river pilot
#

ok, thanks for clarifying.

maiden pawn
# river pilot ok, thanks for clarifying.

It just helps easier defining code architecture u wish to have (through incremental refactoring preferably, although u can be crazy to try accounting everything from beginning)

#

Code refactorability allows reaching perfection (including easier reaching pure stuff, if that is your goal)

#

Any code is changing to meet new requirements and more written code.
Any dev is writing shit on first try (often enough)

#

Refactoring is driven force to reach perfection closer

#

And static typing is very important tool for that

maiden pawn
# river pilot I agree that static typing can make it easier to understand code, and help with ...

--
U can just change something from class method to static method for example. That is already helping you to try writing something more pure if u wish. (Static typing will mark u where u still haven't rewritten previously used instance attributes, that u may be changed)
Typing is a tool that helps u to reach easiest to any code architecture u wish as end result. (Which can be anything u set goals for)

#

It helps to achieve code architecture goals far easier

river pilot
maiden pawn
# river pilot a static method can have side effects just as much as a class method can. I gue...

yeah, side effects are tricky.

I think the most major part of static typing regarding global state changes and side effects included...

That u can actually explicitly define what is public allowed (or private and really restricted to access) in class instance or in module.
U can just restrict from usage anything changing global state (at least for modules that u wrote and having as changeable part of application, or libraries u can change) if desired and going more pure if wishing

#

that is at least possible in Golang, where variables or function or method become public accessable to code outside of module only if u allowed it
(Same for Java)

maiden pawn
#

Therefore u can restrict to have getters only and no setters for your other code parts to access
I don't remember having anything for modules though in python

maiden pawn
pearl cliff
#

if you instantiate your own random.Random instance, the mutated state remains local to that instance

maiden pawn
#

Yeah, I learned pseudo(and real) random generators and wrote my own as part of uni course. No worries here

pearl cliff
#

right, so you should know that the PRNG very much does have its own mutable state and that generating a random number mutates that state

#

and because it's a shared global instance of the PRNG then that state is definitionally shared global state

river pilot
#

I had a hard-to-find bug that boiled down to that global random-module state and an unexpected mutation in it.

#

I ended up talking about it at PyCon

pearl cliff
#

fun, what was the title of that one?

maiden pawn
river pilot
pearl cliff
proud nebula
pearl cliff
#

never considered using sys.settrace for finding stuff like this

proud nebula
#

I like time-machine on by default in tests. It would be nice to do the same for randomness.

maiden pawn
#

I am happy with just 90% of getting close

proud nebula
maiden pawn
#

Also, pure python problem, solvable by using real typing friendly language

#

I think it should not be hard to write python linter that forbids private prefixed python objects from usage in other modules (similar to go, allow private objects of specific folder used only at same level parent module, including in all tests)

#

sounds like really easy stuff to do to me

#

thus, solvable problem even for python

river pilot
# maiden pawn thus, solvable problem even for python

there are two reasons people keep talking about this: 1) you keep connecting function purity to static typing, and there just isn't a connection. They are both good, but they are unrelated. 2) Things like private/public and getters/setters can defend an object against mutation (to an extent), but doesn't ensure that any given function is pure.

maiden pawn
#

I am happy with 90% result and achieved lesser code complexity at minimum cost through automatically enforced architecture means

proud nebula
proud nebula
pearl cliff
#

algebraic effects in particular are really damn cool and my "project wishlist" for ~2 years now has been to build something in koka or the new ocaml effects system

maiden pawn
# proud nebula What does that even mean? ๐Ÿคฃ
class PublicInterface(Protocol):
    public_var: str
    def meth(self) -> int:
        ...

class ImplementedStuff:
    def __init__(self):
       self.public_var = "abc"
       self._real_private = 123

    def meth(self) -> int:
        ...

    def asd(self) -> int:
        ...

b: PublicInterface = ImplementedStuff()
#

that alone should help to use only meth as public method, and public_var as public
mypy will prevent you from using the rest of stuff that is having more private nature

pearl cliff
pearl cliff
#

therefore in this example b.meth() can still mutate _real_private -- it depends entirely on the implementation of the particular PublicInterface instance that you have

#

it's almost a worse situation than before. now you are quietly, implicitly, internally mutating state!

maiden pawn
# proud nebula Two super senior devs telling you that you are wrong isn't enough? Need more? ๐Ÿคฃ

i had senior dev as former tech lead, that in 11 years of his career in bank
and all the previous career, never learned even how to unit test code, but nevertheless he wrote... full applications for work from zero.
They died due to lack of maintenance during new year change, since it was hard to verify all code changes necessary to do across the code
Senior = not equal to not doing shit ๐Ÿ˜…

pearl cliff
# proud nebula Yea that would be cool.

nim has a "checked effects" system too that's also been useful in my limited plunking around. it doesn't have polymorphism or any of the fancy mathematical elegance, but it works and i would feel comfortable having it around in a production codebase

#

anyway my point is that static types in python and most other languages convey no guarantees one way or another about runtime effects, because runtime effects are explicitly and deliberately beyond the scope of what they can convey

maiden pawn
pearl cliff
#

traditional interfaces convey that information by convention, documentation, and trust, rather than statically-checkable assertions

pearl cliff
#

what's unfortunate specifically about haskell & friends is that IO can be damn near anything. filesystem? memory buffer? standard input/output streams? network?

#

i assume that actually knowledgeable haskell people have ways to specify in more detail

maiden pawn
# pearl cliff sorry if i'm missing some context here, but the whole problem with the particula...

sure, i agree that you can't get rid of state mutations from this function easily...
#unit-testing message as last point i pushed, that static typing helps to minimize amount of side effects through usage of real public and private methods (if that is your goal). Since you can define more restricted access to global state across your code (at least in Golang or Java, where it is possible to define what are public variables, classes, methods of a module)

pearl cliff
#

as in your example, hiding the mutable state access inside private implementation detail actually makes it harder to see what's going on (in my opinion)

maiden pawn
pearl cliff
#

unless the interface is deliberately meant to do something with global state, it's borderline trivial to accidentally (or deliberately) put in global mutation behind the scenes

pearl cliff
maiden pawn
#

yeah, sure it is possible.

pearl cliff
#

no, i'm saying the opposite

#

i'm actually saying that decoupling makes it harder to manage mutable state, because you don't have visibility or control into how things work

maiden pawn
#

horrible stateful things and feel like it's OK because it's abstracted away behind an interface
are you? semantic coupling is when you need to call some abstracted behind interface code in certain way, knowing about its internal working and how it mutates in order to achieve result

#

we just need to define better interfaces/abstractions, that make possible to use in a right way, without knowing how they are working under the hood

pearl cliff
#

i see, sure. in that sense yes, mutable state inside some private implementation always causes semantic coupling between that private implementation and the application that's calling it

#

or almost always

maiden pawn
hexed cloak
#

in this specific case there's a monad for Random state

pearl cliff
maiden pawn
# pearl cliff yes, that's true. but that's what i was talking about above: that's convention a...

and my point, that machine can easily statically check that devs do not break defined interface, as long as we have real public/private methods. (possible in Golang/Java by default)
problem to achieve in python yeah... Abstract and Protcols can give it somewhat, but otherwise we need to write our own linter (or adding as feature to mypy/pyright) that just forbids accessing private variables/classes outside of module scope, then i think it is achievable in python. (And running this check in CI)

P.S. of course we can't though expect all devs writing interfaces to libraries that push dev-users to correct its usage... so semantic coupling is unavoidable, since it depends on dev skill level to write their library in the way that semantic coupling is not present, and interface of lib indeed helps to use it without knowing about its internals

pearl cliff
proud nebula
pearl cliff
# maiden pawn and my point, that machine can easily statically check that devs do not break de...

i feel like we're going in circles. no, you can't have a machine check it. adapting your example slightly:

class PublicInterface(Protocol):
    # NOTE: get() is expected to be memoizable and should always return
    # the same result for any given instance.
    def get(self) -> int: ...

class ImplementedStuff:
    def __init__(self):
       self._real_private = 123

    def increment(self) -> int:
        prev = self._real_private
        self._real_private += 100
        return prev

    def get(self) -> int:
        return self._real_private

a: PublicInterface = ImplementedStuff()
b: PublicInterface = ImplementedStuff()

table = dict(a=a.get(), b=b.get())

assert b.get() == table["b"]

b.increment()

assert b.get() == table["b"]  # ERROR

what are you proposing that we add to this example in order to be able to statically detect and prevent this?

even with a custom-written set of tests that hooks into runtime code to inspect behavior, this might not be easy. you're getting into territory of needing something like pytest-mock "spy" to be able to have any control over this situation at all.

proud nebula
#

Haskells prelude story seems so messy :(

#

OCaml too.

pearl cliff
proud nebula
#

I wish Elm had some reasonable monads or something. It's too simple.

maiden pawn
proud nebula
pearl cliff
# maiden pawn added into strict mypy'ed file. your code will error in trying to access b.incre...
class PublicInterface(Protocol):
    # NOTE: get() is expected to be memoizable and should always return
    # the same result for any given instance.
    def get(self) -> int: ...

class ImplementedStuff:
    def __init__(self):
       self._real_private = 123

    def _increment(self) -> int:
        prev = self._real_private
        self._real_private += 100
        return prev

    def get(self) -> int:
        return self._real_private
        self._increment()

a: PublicInterface = ImplementedStuff()
b: PublicInterface = ImplementedStuff()

table = dict(a=a.get(), b=b.get())

assert b.get() == table["b"]
assert b.get() == table["b"]  # ERROR

(this is pretty much what a PRNG does, as you know)

proud nebula
#

So. AGAIN. no.

#

Three people telling you that you are wrong. How many people will it take? ๐Ÿคฃ

maiden pawn
# pearl cliff ```python class PublicInterface(Protocol): # NOTE: get() is expected to be m...

sneaky, yeah.

P.S. of course we can't though expect all devs writing interfaces to libraries that push dev-users to correct its usage... so semantic coupling is unavoidable, since it depends on dev skill level to write their library in the way that semantic coupling is not present, and interface of lib indeed helps to use it without knowing about its internals
developer did not think throughly in defining interface that is pushing always to correct usage of library.
responsibility on library dev to write its interface in a way that semantic coupling is not possible.

Static typing still helps here, since... we can at least localize the problem? We know how the code will be used in other code parts, as long as we defined interface that forced certain usage of a library.

#

So just a matter solving this problem at the level of this particular library/module. and then fixed result will propagate through the rest of the code automatically

pearl cliff
#

Static typing still helps here, since... we can at least localize the problem? We know how the code will be used in other code parts, as long as we defined interface that forced certain usage of a library.

my entire assertion is that static types do nothing for us here, it's the exact same as if you had no type annotations

#
class ImplementedStuff:
    def __init__(self):
       self._real_private = 123

    def _increment(self):
        prev = self._real_private
        self._real_private += 100
        return prev

    def get(self):
        return self._real_private
        self._increment()

a = ImplementedStuff()
b = ImplementedStuff()

table = dict(a=a.get(), b=b.get())

assert b.get() == table["b"]
assert b.get() == table["b"]  # ERROR

this is the same code, no annotations. static types did nothing for us. the problem is the same in both cases.

maiden pawn
# pearl cliff would you say that `rand = random.Random() ; rand.randint(1, 10)` is sneaky, or ...

would you say that rand = random.Random() ; rand.randint(1, 10) is sneaky, or a problem with the design of random?
there is at least some merit of problem in design of random
Less confusing could be having interface

from my_random import GlobalCurrent

rand = my_random.PsuedoRandom(start=my_random.GlobalCurrent) # don't allow default values perhaps?)
rand = my_random.TrueRandom()

That alone and restrictired of usage random only if in this way it was instantace created (we can fix this issue for our code if we code isolate this behavior into only our allowed module)
Would have helped to spot quicker if you are using a thing you intended to use

#

we can... convey how library works to some extend, through how functions are named, and what input is required for its usage?

#

there is certain harm to comfort of usage though. it has its own cost

maiden pawn
#

less time will be consumed in debugging this issue

#

once you fixed issue at the level of library and interface you expose, correct usage will propagate through the rest of the code automatically ๐Ÿ˜› (if there were needed changes in exposed interface in order to achieve more correct library usage)

#

so... shorter to chase situation than without static typing

  1. fixing issue only at the level of certain library/module code. That issue if reached outside of the module, then it is replicable within called public methods/vars
  2. and/or fixing public exposed interface (the rest of code receives message to fix itself by static typing enforced)
#

in both situations (with typing), it is easier to refactor code and fix issue to new fixed state across all the present application code ๐Ÿ˜‰ (for situation number 2)
and to read what the code was doing, in order to understand and debug issue faster (for situation number 1)

river pilot
#

@maiden pawn we all agree: static typing lets you provide more information about your code. More information leads to fewer mistakes. Better names are also better.

proud nebula
#

But static typing in python does NOT deal with mutation. At least not yet.

still quail
#

๐Ÿ‘‹ hello, working on learning to use pytest & moto for testing my AWS client wrapper modules, I haven't been able to find any specific communities around moto & struggling to figure out how to assert methods that would return json.
anyone familiar enough with these tools to lend a hand please?

crimson root
hexed cloak
crimson root
#

ait my bad. I thought maybe someone here could help

blissful aurora
maiden pawn
#

now do strict static typing in ide that can show it on a fly recalculated in precise code lines ๐Ÿ˜…

blissful aurora
#

Im already implementing kinda strict static typing :(

maiden pawn
#

rapid feedback, and ability for rapid fixes and experiments matters in order to keep sanity and receiving enjoyment out of this process

blissful aurora
#

You can be sure i do
PyCharm offers some pretty powerful functionalities and integrations with unittesting

blissful aurora
#

with the press of a button i can test the entire application
or if i want, because the structure of my unit-tests exactly mirrors that of the production code, i can test individual pieces of code from entire layers to individual components, subcomponents and scripts and individual classes and functions

blissful aurora
#

manually :,/

#

like,
this somewhat represents the structure of my code and my tests

src
--presentation_layer
----component1
------__init__.py
------script1.py
------script2.py
----component2
------__init__.py
------script3.py
------script4.py
--logic_layer
----component3
------...
unittests
--test_presentation_layer
----test_component1
------test_script1
--------test_function_func1.py
--------test_function_func2.py
------test_script2
--------test_function_func3.py
--------test_function_func4.py
----test_component2
------test_script3
--------test_function_func5.py
--------test_function_func6.py
------test_script4
--------test_function_func7.py
--------test_function_func8.py
--test_logic_layer
----....
#

pycharms identifies every directory/script/class/function prefixed with 'test_' as a runable test or something that contains tests and allows you to just run it/the tests it cointains without any configuration
this is really cool
so i just prefix everything with 'test_' and then i can just run any scope of tests at the click of a button

#

and again, since the structure of the tests is a mirror of the production code, the scopes match those of the production code perfectly
pretty neat :)

prime willow
#

folks, can someone help me with mocking inside a pytest fixture.
here is my class

    def __init__(
        self,
        domain: str,
        problem_set: str,
    ):
        self.domain = domain
        self.problem_set = problem_set
        self.consumer = None
        self.producer = None
        self.consumer_topic = None
        self.producer_topic = None


    async def _initialize(self):
        print(f"called initialize")
        self.consumer_topic = "consumer_topic_name"
        logger.info(f"Consuming from the topic: {self.consumer_topic} ...")
        self.consumer = AIOKafkaConsumer(
            self.consumer_topic,
            bootstrap_servers=BOOTSTRAP_SERVERS,
            group_id=f"{self.consumer_topic}_consumer_group",
            auto_offset_reset="earliest",
            enable_auto_commit=False,
        )
        await self.consumer.start()
        self.producer_topic = "producer_topic_name"
        logger.info(f"Writing to topic: {self.producer_topic} ...")
        self.producer = AIOKafkaProducer(
             bootstrap_servers=BOOTSTRAP_SERVERS,
        )
        await self.producer.start()```
#

and I'd like to create a pytest fixture for it and below works

@pytest.fixture(autouse=True)
@pytest.mark.asyncio
async def processor():
    processor = Processor(domain, problem_set)

    processor.producer = MockKafkaProducer()
    processor.consumer = MockKafkaConsumer()
    yield processor

however when I try to patch the objects, it doesn't work meaning it isn't using the Mock classes instead it is connecting to Kafka directly. I don't seem to understand what I'm doing wrong. Can someone suggest?

@pytest.fixture(autouse=True)
@pytest.mark.asyncio
async def processor():

    with patch.object(aiokafka, "AIOKafkaConsumer", new=MockKafkaConsumer), \
         patch.object(aiokafka, "AIOKafkaProducer", new=MockKafkaProducer):
        processor = Processor(domain, problem_set)
        await processor._initialize()  
        yield processor
kind meadow
prime willow
prime willow
#

mm, so show should I change this?

kind meadow
#

What do your import statements for aiokafka look like

prime willow
#

i have the processor class defined in a file called base.py and in that I import it like from aiokafka import AIOKafkaConsumer, AIOKafkaProducer

kind meadow
#

You're experiencing the problem that documentation describes.

#

You're trying to patch the class in aiokafka but it is too late - you've already imported base.py which in turn has already imported the real consumer and producer and stored them in new names

#

So you'd need to patch the producer and consumer in base.py

prime willow
#

like this with patch.object(base.aiokafka, "AIOKafkaConsumer", new=MockKafkaConsumer) ?

kind meadow
#

No, base does not have an aiokafka attribute. It's probably just patch.object(base, "AIOKafkaConsumer"

prime willow
#

I see! I'll try making that change

viscid basalt
#

๐Ÿค”

#

But yeah, won't help with your interface

pearl cliff
#

yeah, that was my argument about how encapsulation might make things worse by allowing you to hide mutation from static analysis tools

maiden pawn
#

by encapsulating complexity to smaller... packages ๐Ÿ˜Š

pearl cliff
#

yeah, there are plenty of good reasons to encapsulate things

maiden pawn
#

also just in general thoroughly testing some encapsulated solution doing all the work is easier

#

than having its logic spreaded all across app

#

you can concentrate and just test mutative thing as much throughly as necessary

#

giving it all performance testing, absolute testing coverage, static typing

#

then the rest of your code can be written by devs with less.... effort, which just use this already quality solution

#

so. even from the point of testing, it is really great to encapsulate things ๐Ÿ˜Š

#

also the rest of the code can be testing much smaller amount of code. Thus saving testing time. and testing complexity is decreased too

#

since there is no need to test throughly already encapsulated stuff that was tested separately. Just smallest formality is enough to check integration

#

Essentially i don't see any reasons not to encapsulate things. Except being careful in not overengineering stuff.

heady crest
#

hello guys, I am learning intermediate python and now I am in the chapter of unit testing can someone explain to me where this is usefull in building an app or something? Thank you

#

?

maiden pawn
# heady crest hello guys, I am learning intermediate python and now I am in the chapter of uni...

Khorikov's book explains in detail why it is useful
Kent beck shows on example how development is done

TLDR: unit testing makes better quality of your application, because it is automatically checked for correctness of its working after each change you make to your code.
unit testing is essential... for any projects made in collobaration with other devs. Helps to integrate code to work with all additions from all devs. And it is essential for long term maintanance of a project (you can rerun tests any time later and to confirm it is still working correctly with new dependencies and changes)

#

Unit testing is essential for any software engineer of level Strong Junior and higher that does programming in commercial environment

heady crest
#

Thank you very much

maiden pawn
#

Unit tests helps to confirm all your code interacts correctly with database stuff at least

#

if it was not unit tested tested = it is not working pretty much philosophy

heady crest
#

This was so much helpfull

maiden pawn
#

because you structure it better, in a way that components are testable

#

it is best to do from the start of a project, during development along side

#

adding tests to project which was already coded... is significantly many magntude times more challenging (because its code architecture was just not made for this, and hard adding tests to project without them, because you aren't sure what is allowed to change without breaking it)

#

unit tests give freedom to change project code as many times as you wish, without knowing its details throughly

#

you just rerun tests, and confirm that all your changes did not affect application correctness

#

So... unit testing is essential to make project Refactorable, Maintainable and Extendable in features ๐Ÿ˜Š

hearty lion
#

Hi guys !

I have a function that takes a list of links, sends requests to them and return a list of all links that returned a code 200.

How would you code a test for that?

I'm new to unittests and it looks easy when working with just numbers and lists and dictionnaries, but I get lost as soon as I have to test things that relies on external stuff (like discord.py or requests or anything like this)

river pilot
hearty lion
jolly tangle
#

I am curious if anyone knows the answer to this question. If someone doesn't answer on time could they answer here?

#1165485676234551317 message

jolly tangle
#

Also I just want to add one thing when I print(field) when running the code outside of pytest the output I get is field= <input id="password" name="password" required type="password" value="">

#

When I run print(type(field)) I get <class 'wtforms.fields.simple.PasswordField'>

limpid perch
#

I moved all my database setup to conftest.py: https://pastebin.com/TA4BaJdw
Struggling now to add one record to the db through my test_alley.py:```py
pytest.fixture(scope="session")
def add_one_alley(session):
alley_one = Alley()
alley_one.id = 1
session.db.add(alley_one)
session.db.commit()

#

I want to add one record before any tests to the database in order to run get/update/delete tests

jolly tangle
#

@limpid perch What about something like this ?

Also username_form, hashed_password_form, email_form are just fixtures that return the username ,password and email . Any question just ask if it doesn't work I will check my notes on calling the fixture.

db.create_all(bind_key) was just because I have 2 db's one for pytest and 1 for the regular code.
@pytest.fixture
def yield_usertest_db():  
    '''

    This is in the /register  route
    Create the db column then yield the selected/queried usertest and finally delete the db.
    yield does not stop the code when yielded.
    '''

    # = with app.app_context() except won't work for pytest
    with app.test_request_context():

        bind_key="testing_app_db"

        def _subfunction(username_form, hashed_password_form, email_form):
            # Create the database and the database table
            db.create_all(bind_key)
            usertest_db = UserTest(username=username_form, hashed_password=hashed_password_form, email=email_form)
            db.session.add(usertest_db)
            db.session.commit()
            # Why can't current_usertest_db be the same name as usertest_db here?
            current_usertest_db = UserTest.query.filter_by(username=username_form).first()   
            return current_usertest_db 
            #return username_form 

         # yield unlike return doesn't stop when called.
        yield _subfunction 
        db.drop_all(bind_key) 

In order to call this fixture if memory serves you just go

  
def test_fixture(yield_usertest_db, username_form, hashed_password_form, email_form)
  usertest_db = yield_usertest_db(username_form, hashed_password_form, email_form)
  assert usertest_db.username == 'username'

Also this is my example I am sure you can make it work for you.

limpid perch
jolly tangle
#

@limpid perch Do you have any idea how to test a flask wtf form?

#

Any question on my example just ask

#

I am not sure if this is the best way but it works

#

usertest_db might not work you might need to return usertest_db.username in the first fixture. Also this is assuming you are using pytest.

gusty heron
#

hey guys, quick question : isn't it possible to use decorators with pytest-mock? I've been struggling with it since 2pm and it's 5 now ๐Ÿ˜ฆ

gusty heron
#

it's more a general question. As far as I am concerned, pytest-mock is just a plugin of unittest.mock so it should be possible

#

isn't it?

hexed cloak
gusty heron
#

I actually tried to import the plugin itself instead of using unittest.mock in the test file. I should just go to sleep...

from pytest_mock import mocker

@mocker.patch('') # this is not valid because mocker.patch does not exist. Obviously because it shouldn't be done that way
def test_something():
  ...
#

I fixed it to ```py
from unittest import mock

@mock.patch('') # that works now
def test_something():
...

ember maple
#

But a fixture gets taken as a parameter to the test function

hallow finch
#

Good morning guys, could a good soul help me with some unit tests? \o/

pearl cliff
# gusty heron it's more a general question. As far as I am concerned, pytest-mock is just a pl...

it's too general of a question to be answerable. decorators are just python syntax, so of course you can use them with any other part of python.

are you talking specifically about the decorators provided by unittest.mock? in that case no, that's specifically not how pytest-mock works. the pytest-mock mocker fixture replaces the unittest.mock decorators and context managers. this is described somewhere in the pytest-mock manual.

#

that is, you use pytest-mock like this:

def test_foo(mocker: pytest.MockerFixture) -> None:
    mocker.patch("x.y.z.foo")
    ...

which is a replacement for:

@unittest.mock.patch("x.y.z.foo")
def test_foo() -> None:
    ...
#

in general, it's not at all correct to assume that Library B works the same as Library A

#

if the libraries lack sufficient documentation to explain their usage, that's a bug, and you'll have to go read the source code

#

but you can't make that assumption. pytest-mock is an alternative interface to the functionality in unittest.mock

safe arch
hexed cloak
hallow finch
#

this my endpoint, i need validate step "validate_webhook_token"

#

the event WebhookEvents.SIGNED_CONTRACTS.value: {

#

Does anyone know how I can do unit testing to validate this functionality?

hexed cloak
mortal jungle
#

Any idea how to test random word shuffling?

eg. func like that:

from more_itertools import random_permutation

def shuffle_word(word: str, loose: bool = True) -> str:
    shuffled = "".join(random_permutation(word[1:-1]))
    if loose is False and not len(word) <= 3:
        while word[1:-1] == shuffled:
            shuffled = "".join(random_permutation(word[1:-1]))
    shuffled_word = f"{ word[0] }{ shuffled }{ word[-1] }"
    return shuffled_word

egzample:
Input -> 'This is the modified content'
Output -> 'Tihs is the moifded conetnt'

maiden pawn
maiden pawn
mortal jungle
mortal jungle
#

I've thought about this

maiden pawn
#

if it is allowed behavior

maiden pawn
#

making random determinated same one for tests

#

it will make tests more repeatable and having no chances to break due to randomness

#

and it will make things easier to debug in case of test breaking

#

since tests will be repeatable to exactly same result in case of failure

mortal jungle
#

Hmm

#

I have to check how to do this

#

Do you mean somethink like random.seed(12)?

maiden pawn
# mortal jungle Do you mean somethink like `random.seed(12)`?

yeah, u can use global set random.seed(12) like that for your tests and it will be already making stuff simpler.
I would have prefered though my own code using it as composition and func args like that though

from typing import NewType

Seed = NewType("Seed", int)

def Randomer:
  def __init__(self, seed: Seed)
    self.rand = random.InitWithSeed(seed)

  def get_int(self) -> int:
    return numbers

randomer_global = Randomer(TrueRandomProbablyFromLib_secrets)

def random_permutation(word: str, randomer: Randomer = randomer_global) -> str
  randomer.get_int()

def test_predictably() -> None:
  input_ = "bla bla"
  output = random_permutation(input_, Randomer(seed=12))
  assert input_ != output

and other code parts using random generators controllably like that
then during tests we could be just overriding it for predictability

pearl cliff
mortal jungle
viscid basalt
ember maple
#

Whenever people asking for behavior testing and people recommend loops and randomization, please know the correct solution is called hypothesis

Stop telling people to make shitty randomized behavior tests

safe arch
maiden pawn
# ember maple Whenever people asking for behavior testing and people recommend loops and rando...

@mortal jungle with people recommending a ton of additional libraries above, I feel necessary to add
That usage of shit ton of libraries is acceptable enough path in every day continuously developed working projects, that run their CI every day multiple times and able to keep up with libraries getting outdated, updated and etc

in general for pet projects (which are maintained only with big skipping periods in long term) and your own libraries the opposite direction is often desired.
Where u use as least possible list of third party libraries as possible.
Keeping your own custom code that implements everything, allows is to remain stable, being depended only on primary language std libs and being fully customizable to everything u need beyond limitations of over opinionated frameworks and libraries
U decrease toll for maintenance in not using every little extra third party lib.
So I don't recommend as obligatory using for pet projects anything but strict mypy/pyright.
(Plus unit testing framework, std unittest or to accept that Pytest is okay enough. May be not for small enough pet projects and std unittest is enough)
Everything else should be very extra careful evaluated if really worthy to be depending on

#

Strict mypy, pyright are always justified for projects like that because they increase readability and improve maintainability in a long run.
They allow building more freely custom code/architecture solutions that will fit every usage case your lib mega

#

Then u get a chance u will continue to like your code in a long run and will be able refactoring to your new skill level every year and adding new features to a full satisfaction

proud nebula
maiden pawn
proud nebula
#

This is how you sound.

ember maple
maiden pawn
#

Strict static typing helps to propagate a better architecture that is better to do from beginning of a project too

proud nebula
#

And there you go again ๐Ÿซ 

river pilot
river pilot
#

I know that I have a hard time figuring out how to use it.

maiden pawn
river pilot
maiden pawn
#

Essentially if u want to build custom unit testable code architecture, u need static typing for more code quality to reach it

#

So...
Just unit testing is simple first start
Code architecture+ static typing + unit testing is more advanced level to test your code

#

hehe, how can u hope to unit test your code for all branches of code logic and types it could be having if nothing defines borders/interfaces of your code ๐Ÿ˜‰

#

Oh right, that is why u recommend hypothesis. To test all possible edge cases instead

river pilot
#

@maiden pawn ok, just know how you are coming across. I'm not sure you're accomplishing what you want to accomplish here.

maiden pawn
ember maple
river pilot
#

it sounds sarcastic

ember maple
# river pilot it sounds sarcastic

Based on the surrounding context I read it as a misplaced and unbecoming point scoring and until clarification is provided I'll take it as that

maiden pawn
# ember maple I'm inclined to take this misrepresenting take malicious

May be a little bit.
I don't believe in my path as the only one existing one.
All approaches to coding serve a single goal in decreasing overall code complexity of a project and helping easier code growth.

U can utilize full boilerplateful code architecture of Django to compensate ability to construct your own typed code structure.
Together with postgres typed enforced structure, it creates a plausible compensation u can further augment with better observability.

There is also completely not understandable to me functional and Haskel programming.

#

They all usually serve a single goal in decreasing code complexity

#

So, I can fairly assume with hypothesis u can test and build stuff in some additional way ensuring quality

#

And since it really generates fakery data to test all edge cases, it indeed sounds to me as typing testing alternative

#

That is it. Enough discord for today. Not answering any longer in nearby time

ember maple
#

So who wants be the bearer of the message that Haskell has quick-check for a reason ...

As far as I'm concerned my impression unfortunately was confirmed

proud nebula
ember maple
ember maple
# proud nebula Trumpism ;)

I see where you are coming from, but I strongly recommend avoiding that Type of labeling as it's easy to go down together with the language One is subject to when communicating

solemn solar
#

Hello everyone, hope you're all doing well. I've a question here, for a web application, is it necessary to unit test the api layer? Say the api layer here is just for request invalidation and response making, and there're already unit tests for the service layer it uses internally.

river pilot
viscid basalt
hexed cloak
#

Maybe testing the service layer directly for getting corner cases in the coverage

solemn solar
solemn solar
solemn solar
viscid basalt
solemn solar
hallow cradle
#

not sure where to ask but maybe somebody here knows the answer;
is anybody familiar with Ipython's internals by chance? I want to know how I can execute a block of code (starting from a string) and get the pretty-repr of the last expression (if there is one)

#

ideally something like execute_code_and_get_last_expr_repr(code: str) -> str:

drifting sorrel
pearl cliff
#

i even write (gasp) tests for internal-only functions if they're hard to get right or critical to the applicatipn

viscid basalt
#

If it's pretty straightforward and/or it doesn't branch then e2e should be pretty ok

drifting sorrel
limber thistle
#

Can someone help me with configuring vscode and pytest?Im trying to make it work for like 5 hours already and i just cant do it.

ember maple
dreamy bough
#

@limber thistle I recommend you create a directory for your project. Then create a virtual environment for that project. Activate that virtual environment and install pytest in using โ€œpip install pytestโ€ or โ€œpipenv install pytest. Open the project directory in VS CODE and make sure that the virtual environment is active. This should setup pytest in VS CODE for you.

limber thistle
dreamy bough
#

Did you install pytest in the virtual enviorment properly?

limber thistle
dreamy bough
#

What do you see in the VSCODE Built-in terminal ?

limber thistle
# dreamy bough What do you see in the VSCODE Built-in terminal ?

i called it again and

 python -m pip install pytest
Requirement already satisfied: pytest in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (7.4.3)
Requirement already satisfied: iniconfig in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (from pytest) (2.0.0)
Requirement already satisfied: packaging in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (from pytest) (23.2)   
Requirement already satisfied: pluggy<2.0,>=0.12 in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (from pytest) (1.3.0)
Requirement already satisfied: exceptiongroup>=1.0.0rc8 in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (from pytest) (1.1.3)
Requirement already satisfied: tomli>=1.0.0 in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (from pytest) (2.0.1)
Requirement already satisfied: colorama in f:\0main_stuff\prog_stuff\projects\pyt\zaman_project\.venv\lib\site-packages (from pytest) (0.4.6)   

[notice] A new release of pip is available: 23.2.1 -> 23.3.1
[notice] To update, run: python.exe -m pip install --upgrade pip
dreamy bough
#

looks like you don't have a vitual environment setup .

limber thistle
#

i guess i have it, i cant call libraries outside the venv requiriments. Also pytest does work, it just can't see directories or something else

dreamy bough
#

Are you using virtualenv or pipenv ?

#
  1. Create a working directory for your project โ€œmkdir example_projectโ€
  2. Create a virtual environment inside โ€œexample_projectโ€ folder โ€œpipenv shellโ€
  3. Install pytest inside the virtual environment.
  4. Done! You can import pytest in your testing scripts. Or run tests from terminal โ€œpytest -vโ€
limber thistle
#

virtualenv
at least when i used pipenv it returned an error

dreamy bough
#

Also, you need to install pipenv first if your getting an error.

limber thistle
#

just created new folder and setuped venv again, added pytest and same stuff.
Pytest does work, it just doesn't work with up directories for some reason

dreamy bough
#

what you mean by "it just doesn't work with up directories for some reason"?

limber thistle
dreamy bough
#

I won't worry about that 'cause pytest looks for test scripts starting with the word "test" and ending with the word "test" in them. ( test_example.py or example_test.py) After that it loooks for your test methods in those files.

limber thistle
#

fair, i tried something and i guess i just cant find a way to give pytest info about other .py files.

dreamy bough
#

when you run "pytest" from a terminal ... pytest will find all the files with tests in them and runs it. That's why i recommend you organize your project in a folder with seperate virtual env.

limber thistle
dreamy bough
#

No. VS Code doesn't create virtual environments for you. What if the virtual environment isn't active? I recommend you learn more about virtual environment and they work then come back to pytest and unit testing. https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/

freeCodeCamp.org

When developing software with Python, a basic approach is to install Python on your machine, install all your required libraries via the terminal, write all your code in a single .py file or notebook, and run your Python program in the terminal. This is a common approach for a lot

limber thistle
dreamy bough
#

No difference. All the same. You just have to understand how it works.

limber thistle
#

Anyway i found out why, you have to put test_ in function name.
ig it was a fundamental mistake after all.
anyway Thanks Edmon for your time.

dreamy bough
#

I already told you that earlier "I won't worry about that 'cause pytest looks for test scripts starting with the word "test" and ending with the word "test" in them. ( test_example.py or example_test.py) After that it loooks for your test methods in those files." ๐Ÿ™‚

limber thistle
#

Yeah, i know, i just didn't even think about namin function wrong. My mistake, but oh well. now i will never forget to do this

dreamy bough
#

I know it's a lot of things to pick up. Believe it or not. I am learning Pytest myslf.

rancid yew
#

lets go

pearl cliff
# rancid yew lets go

i don't think i could ever eat 56 donuts even in a month. hopefully hussain likes to share

rancid yew
#

he was pretty hungry

limpid sentinel
#

Hey guys, can you give me advice on how could I test my controllers which are supposed to make raw sql queries to database and retrieve/respond with the data?

hexed cloak
#

You can rollback the transaction or snapshot the database and restore it

limpid sentinel
# hexed cloak You can rollback the transaction or snapshot the database and restore it

oh, actually its a good idea. thank you for advice, but one more question, how can I make a async setup and teardown methods? I've tried to use async package for pytest but im getting a runtime error RuntimeWarning: coroutine 'TestUserController.setup_method' was never awaited

class TestUserController:
    @classmethod
    @pytest.mark.asyncio
    async def setup_method(cls) -> None:    
        await DatabaseManager.start(
        settings.POSTGRES_DB,
        settings.POSTGRES_USER,
        settings.POSTGRES_PASSWORD,
        settings.POSTGRES_HOST,
        )
        print('setup')

    @classmethod
    @pytest.mark.asyncio
    async def teardown_method(cls) -> None:
        print('teardown')
    

    @pytest.mark.asyncio
    async def test_get_by_id(self, mocker):
        # mocker.patch(target='app.controllers.user.get_by_id', return_value=self.user['id'])
        # test_data = await get_by_id(self.user['id'])
        
        # assert test_data.id == self.user['id']
        print('test')
        assert 1==1
limpid sentinel
#

hm... is there a possibility that pytest might block connections to database? scince I am getting error ```E socket.gaierror: [Errno 11001] getaddrinfo failed

C:\Users\Arata\AppData\Local\Programs\Python\Python311\Lib\socket.py:962: gaierror```

#
@pytest.fixture
async def setup_and_teardown():
    await DatabaseManager.start(
    settings.POSTGRES_DB,
    settings.POSTGRES_USER,
    settings.POSTGRES_PASSWORD,
    settings.POSTGRES_HOST,
    )

    print('setup')
ember maple
limpid sentinel
hexed cloak
limpid sentinel
proud nebula
hexed cloak
limpid sentinel
hexed cloak
limpid sentinel
hexed cloak
#

You put everything in one paste

#

Looks like something is wrong with DatabaseManager

limpid sentinel
#

Oh you ment paste, sorry

limpid sentinel
#

actually w8, I solved the problem. Looks like reason was in my pytest.ini, i wrote all variables as a string which caused the error

hexed cloak
#

Btw you have two async test plugins anyio and pytest-asyncio you only need one

limpid sentinel
pearl cliff
#

I did the same thing for a while, I didn't realize anyio had its own plugin

dreamy bough
#

Hi team,

Iโ€™m looking for tutorials and examples on implementing integration tests with Pytest. I found a couple with Pytest and Flask. But Iโ€™m still looking. I prefer guide/tutorials with pre-production (staging environment) codes and code examples, implementing integration tests that actually tests the application.

Thanks

maiden pawn
# dreamy bough Hi team, Iโ€™m looking for tutorials and examples on implementing integration te...

As I have discovered, it is actually more challenging than expected to do that.

Real integration tests can be done only if u raise instance of service in background (for example as a thread)... And do all the desired tests against it.

There is Robot framework for that also, but I think it is nasty piece of tech that increases difficulty too much for that and lacks sufficient flexibility and dev comfort.

Tldr: i think u should be ideally using for integration testing, just Pytest fixture that launches as a thread working application in a testing mode but with real web server pretty much and just run tests against it.

#

Best to consider in advance overrides with mocks for third party APIs nevertheless though, so raised web server should still have programmatic access for additional tunning before it was launched

#

In theory since u run it as thread, it could be still mockable on a fly during tests

#

needing to test it. Haven't checked yet that it will work flawlessly in python.
If it will work, it will make integration testing at a far superior code comfort than Robot framework can ever hope to provide (for ffs it is not even having debug mode)

#

P.s. Any... Any! Framework testing client is not bringing sufficient level of integration testing. But raised in a thread web server should

#

Tried in Django testing client with Requests client, it was still not enough at least

dreamy bough
#

Okay. I do full stack with Django and react. I perfer anything with Django. Interesting.

#

Let me understand ... please tell me if I am wrong So to implement real integration test with Python and Django. I will create an EC2 instance running Ubuntu. Run the Django app ... Then use Pytest fixtures to test an instance of the app running in real time. Am I correct?

maiden pawn
maiden pawn
# dreamy bough Let me understand ... please tell me if I am wrong So to implement real integra...

yeah, basically that's it. the part regarding thread is kind of important to increase comfort for tests though, u should be still having code access to this thread from your runnint tests, therefore have sufficient flexibility to mock not needed third party libs and erase easier data between test runs (ideally we should try still sticking to the default of erasing data between tests after all)

#

So ideally your thread launches web server in a programmatic way (for gunicorn there is way for incode server raising), without any shell shenanignans

#

that will give u better code flexibility and in theory your debugging should be still able to traverse if necessary into code executions of a web server

#

that should make it flawlessly easy to maintain such integration tests

#

nothing of this is present if u will go with Robot framework which is default standard for integrations :/

dreamy bough
#

Yeah I am familiar with gunicorn. That's what I use to run Django app in prodution. gunicorn and nginx. I think by default it spins multiple workers when running django app.

#

and you can of course change the number of gunicorn workers as needed . but usually about 4-5 usually runs and nginx runs 1 master and 2 workers.

maiden pawn
#

we need web server running as one thread only (for code accesability, for mocking, for debugging traversing into app code)

#

some configuration to check for web server preferably

#

u will not have access to Processes. even in this way it stilll better than robot i think
but with having web server running as single thread it should be even better

pearl cliff
maiden pawn
#

oh, that i don't even consider for integration testing. it still unit testing to me ๐Ÿ˜…

#

i am more speaking for integration as running full instance of a web server and accessig it without test clients (like Robot framework offers doing)

pearl cliff
#

i mean, it's not a bug for bug EC2 replica but we do run endpoint-to-response tests that way

#

and yes we use the starlette test client (in our case via fastapi)

#

you can definitely do the "real" integration tests like you describe of course, but i think it's an 80/20 thing

maiden pawn
#

still unit testing to me then. it is not bringing sufficient level of integration.
running web server as a full instance is bringing far more assureness of code correctness in a real way

#

at least that i got when testing my library. without such tests, things are discoverable only during staging

#

such tests are meant to replace need of depending on staging manual checking (for good percentage)
Or having cheaper e2e tests alternative

pearl cliff
#

yeah ultimately it's good to have both

#

but again, you can get pretty far with the local setup. it also forces you to avoid relying too much on implementation details of the deployment environment and ensures that the dev/test/debug loop can stay tight, which is very important

dreamy bough
#

I understanding everything you said expecte for the setup here "hmmm. each worker is its own child process i think
we need web server running as one thread only (for code accesability, for mocking, for debugging traversing into app code)
some configuration to check for web server preferably
u will not have access to Processes. even in this way it stilll better than robot i think
but with having web server running as single thread it should be even bette". So I need the entire application running in a single thread? I have to manually configure/ create a Python script that runs the entire Django project/app in a single thread on EC2 then start the integration test?

maiden pawn
#

Ergh, I think running integration tests with any web server. Just not using test client, should just check stuff more thoroughly. We can disregard miss matching deployment environments here for the sake of having locally (and CI) easy runable integration tests with full debug access

#

We will have easy room to run them for every commit in CI and full debug support. That is important enough to disregard deployment miss matches

maiden pawn
#

The part regarding threads is not super important, u can still have separate injected code on start up of application (separate wsgi/asgi.py to raise test server), making this app instance easiest testable

#

But it will be nice to have for better debug and more mockability nevertheless

#

U need finding correct web server for that (may be Uvicorn can offer that or smth)
Or may be default Django dev server code has option to run its web server in code without extra process born (it should be on purpose not optimal, without extra processes)

proud nebula
dreamy bough
#

I am after the encyclopedia definition of integration tests and what integrations tests means in general. Just want to understand how to write code and implementing solutions that tests different parts of the application code and how the different components work together. I understand unit testing, fixtures, setup methods, assert with pytest and Nunit. But I don't know how to implement integration tests in code. I understand the term "integration tests" but not actaully writing the code.

maiden pawn
#

u can still select during this integration testing, which exactly integration you are checking

#

@pearl cliff named as integration testing, utilizing as container in database same as in prod. and he is correct. it is still technically integration testing (i prefer to have it as default for unit testing though)

proud nebula
maiden pawn
#

people name running tests in EC2, so they would be having als filesystem same as in prod. But if u use dev machine with Linux and same filesystem, then it is not an issue too

proud nebula
#

Right now I heard "what <UNDEFINED TERM> means in general". Which is obviously not answerable.

maiden pawn
#

i was speaking in adition attempt to bring integration testing with integration of a real web server running your app.

#

as a more ultimate check (which brings our integration testing very close to domain of almost e2e testing)

dreamy bough
#

Integration testing (sometimes called integration and testing, abbreviated I&T) is the phase in software testing in which the whole software module is tested or if it consists of multiple software modules they are combined and then tested as a group. Integration testing is conducted to evaluate the compliance of a system or component with specif...

proud nebula
#

assert foo(bar(2)) == 5 can be an "integration test" in that definition, if foo and bar have individual unit tests and are from different "modules"

dreamy bough
#

Thanks @proud nebula . Your probably correct with this example. That's not what I am after. My question is just about integration tests in the Testing Pyramid. You have End 2 End Test (E2s), Integration Tests and Unit Tests.

proud nebula
#

I used to work on a project with this definition:

  • unit: no database, 100% in-memory
  • integration: touches database
  • e2e: uses a browser to test the full stack
proud nebula
#

Programming is like 99% about carefully thinking about semantics ("the meaning of words"). So be VERY mindful of when you don't exactly know in detail what a word is supposed to mean, or when you aren't certain the other person might not agree on the definition.

dreamy bough
#

I'll admit I don't know that's why I asked.

proud nebula
#

good :P

#

But also know what everything Darkwind wrote was based on his definition, which you have no idea what that definition is. This is your life as a programmer :P

dreamy bough
#

I agree. I searched online/google before posting the question here. I found few examples and was still unsure. That's why i came here. I understand you still have to think critically about the answers and make informed decisions.

pearl cliff
proud nebula
proud nebula
#

like.. a LOT

pearl cliff
#

which means the term "integration" covers a big range. it's everything between "unit" and "e2e"

pearl cliff
#

so the database + app

proud nebula
#

I assume you meant "more than one component you wrote"?

pearl cliff
#

sorry component was not the right word

proud nebula
#

Because otherwise it's not a unit test if you call str.replace :P

pearl cliff
#

so for example if you have a webhook you can have an integration test without a database involved

#

or a client calling an internal api

dreamy bough
#

Thanks again for your help @maiden pawn @proud nebula . I just need practice implementing tests now.

proud nebula
plush vale
viscid basalt
#

I would argue that if you swap your postgres for an in-memory sqlite it's still an integration test

dreamy bough
#

PostgreSQL and SQLIte are external depdencides. I think integration tests is more about testing the functionalities of your application code and how it interact with external dependencies. It won't matter if your using PostgreSQL or SQLIte. As long as the methods in your own production code are calling the database correctly and performing database operations then your doing integration tests. Also, you assume that PostgreSQL, SQLite and other third party application your production code depends on are property tested and just focus on your own production code.

plush vale
#

An in-memory implementation would be e.g. storing the data in a list in the application's memory for the duration of the test, such that the data never leaves the application.

proud nebula
#

Hell, so is the CPU and memory. You have to be pragmatic about these things, or your brain will break.

dreamy bough
#

Okay.

viscid basalt
plush vale
#

I'm just elaborating on how I understand the definition of integration tests. I didn't intend to say that you shouldn't do them.

proud nebula
#

I think the distinction is largely useless. Those terms have no effect on how the code looks or behaves.

#

If there's a @pytest.mark.django_db annotation on a test though, that's very clear what that means

plush vale
#

Yeah, I agree that it's largely useless in general. An "integration test" usually has a defined meaning within a project or a team, but the definitions are not standard across the industry. It's interesting to see how others use the terms.

viscid basalt
#

Honestly you could mostly "avoid" writing unit tests by writing integration tests instead ๐Ÿ˜…
I'm still not sure if it's a good or a bad thing

proud nebula
#

Imo you test on the level where you can verify things easily and fast. Whatever that is. Depends on the situation.

#

Might be manual testing by clicking around, might be totally pure functions with no dependencies...

plush vale
#

Yeah it depends on what you need. Broad integration tests can get you a lot of coverage for little effort. But if you have a lot of business logic in your application, it helps to decouple it from external resources. When contained, it's easier to test with granular assertions. Different tools for different needs.

#

If there are a lot of logical paths, orchestrating things to hit them all can be difficult and indirect. Then you have large, slow, complicated tests that are difficult to maintain.

pearl cliff
#

i once worked on an app where the only tests were snapshot-based e2e/integration tests. in an unfamiliar programming language, no less (not python). that really tested my resolve.

proud nebula
viscid basalt
# pearl cliff the problem with integration tests is that debugging can be really hard if somet...

Depends on how your integration tests are built, if you're using some kind of snapshot - yeah, in general my db integration tests look like this:

# test_retireve_entity.py
@pytest.fixture
async def entity(session: AsyncSession) -> Entity:
    entity = Entity(...)
    session.add(entity)
    await session.flush()
    return entity


async def test_not_found(http_client: httpx.AsyncClient) -> None
    response = await http_client.get(f"/entities/{uuid.uuid4()}")
    assert response.status_code == 404


async def test_ok(
    http_client: httpx.AsyncClient,
    entity: Entity,
) -> None:
    response = await http_client.get(f"/entities/{entity.id}")
    assert response.status_code == 200
    assert response.json() == EntitySchema.model_validate(entity).model_dump(mode="json")
#

Since all state is set up in tests I don't really see a problem pithink

lunar lark
#

Hello all!

I am tryong to mock a coroutine, so I can generate some simple unittests. However, this doesn't work as I exepct.

I have following function:

async def unittests(runner):
    return await runner.with_exec(["poetry", "run", "pytest", "tests/unittests"]).stdout()  # (1)

Which I want to test:

@pytest.mark.asyncio
async def test_pipeline():
    await unittests(mock_runner)
    assert mock_runner.assert_called_with(["poetry", "run", "pytest", "tests/unittests"])

The problem is, that I cannot build a mock, which provides the .stdout() and therefore the test fails.

await mock_runner.with_exec().stdout()
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: 'coroutine' object has no attribute 'stdout'

Any idea how the mock needs to look like?

Of course, that didn't work ...

mock_runner = mock.AsyncMock()
mock_runner.with_exec = mock.AsyncMock()
mock_runner.with_exec.stdout = mock.AsyncMock()
lunar wave
#

!paste

bitter wadiBOT
#
Pasting large amounts of code

If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/

After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.

lunar wave
#

just needed the link

dreamy compass
#

hello everybody

#

how do i unmute my self??

#

i realy need to talk

#

sombody??

#

aswer

#

answer*

proud nebula
quartz edge
bitter wadiBOT
#
Voice verification

Canโ€™t talk in voice chat? Check out #voice-verification to get access. The criteria for verifying are specified there.

lament heath
lament heath
proud nebula
sacred depot
#

Hello

#

What is the equivalent, using unittest.mock, of Java's Something mock = mock(Something.class)? ie, I want that class to have "dummy" methods which do nothing but which I can query to see whether they are called etc

#

I want to mock a threading.Timer and check whether it's been called with cancel()

sacred depot
#

def test_timerIsCancelledIfItExists(self): state: BlinkerState = self.state timer = mock() state._timer = timer state.resetOrUpdateTimer() verify(timer, times=1).cancel()

#

I love mockito

#

It's sooo obvious to use

hexed cloak
#

Or just a plain Mock(spec=SomeClass)

sacred depot
#

Hmmwell, uh, not really

#

For instance I want to be able to do something like when(mockedObject.someMethods(some, arguments)).thenReturn(whateverIWant) (or thenDoNothing() if it's a None method)

#

or .thenRaise() etc

#

Maybe mockito can do that, I'll check

#

OK, mockito can do that

#

On "real" instances too, unlike in Java :p

maiden pawn
silk crescent
#

how can I make mock request ? I can see requests-mock module but I think it's trying to make a http request to the url. is there a way to mock that requests without making an actual request ?

#

or I have to pass a live URL ?

silk crescent
#

this is what I'm doing & getting requests_mock.exceptions.NoMockAddress: No mock address: GET http://localhost:12345/endpoint

silk crescent
#

nvm got it. by replacing the variable with value http://localhost:12345/endpoint

pearl cliff
silk crescent
#

All good now thanks anyways

maiden pawn
#

@merry summit : it was hard to find time to even write any tests.
potentially mm not exactly correct may be approach if u have issues with it.
Could u describe your language/stack and how you start to write some features. Like voice steps u do to try writing first code lines?
and what IDE/debugging tools u use

merry summit
#

Voice steps?

maiden pawn
#

how do u check u write it correctly?

#

what is your language/tech stack also

maiden pawn
#

as if you were speaking to dummies/brain dead robots or smth

merry summit
#

yeah sure, maybe tomorrow

#

also i forgot

#

after merging everything into develop, integration testing comes

#

so i guess if there are errors or bugs

#

the time to fix it is then?

maiden pawn
#

if it is not automated and happening after PR is already merged, then it is "Manual QA"

dreamy bough
#

When do you use the โ€œpatchโ€ method and when should you use the โ€œMockโ€ or โ€œMagicMockโ€ when mocking?
Both seems to do the same thing. Also, I read that itโ€™s better to just use โ€œMockโ€.

dreamy bough
#

Hi @maiden pawn ! Thanks again ๐ŸŒฎ ๐Ÿ™‚ !
What you told me about how to implement integration tests a couple of days ago makes more sense now: Just use Pytest fixures that launches as a thread working application (create pytest fixures) and web server (or docker) and just run tests against it.
It seems to be Integration Tests is what you described and just testing a bunch of HTTP requests methods because most of what I see is doing integration Tests for APIs and APIs are just ENDPOINTs โ€ฆ of course you can return JSON/data. Databases isn't an API, but we are still testing an external source and trying to verifiy (assert) if the test is failing or passing. But yeah from what I understandโ€ฆ unit testings is testing against application code and Integration Tests is testing against external dependencies which are web services most of the time. Iโ€™m speaking from web development perspective. Integration Tests for something like gaming or other platforms would be different.

import pytest

@pytest.fixture
def fixture_1():
print('run-fixure-1')
print('fixure-1 ... Setup PostgreSQL Connections here.')
print('fixure-1 ... Collect data from the database (PostgreSQL) here. ')
return 1

@pytest.mark.slow
def test_example():
print("test1")
assert 1 == 1

def test_example_1(fixure_1):
num = fixture_1
assert num == 1

maiden pawn
# dreamy bough Hi <@370435997974134785> ! Thanks again ๐ŸŒฎ ๐Ÿ™‚ ! What you told me about how to i...
@pytest.fixture(scope="session")
def fixture_1():
    print('run-fixure-1')
    print('fixure-1 ... Setup PostgreSQL Connections here.')
    print('fixure-1 ... Collect data from the database  (PostgreSQL) here. ')
    return 1

considering the cost of raising full web app, or opening connections and doing migrations.
I recommend as much as possible to utilize "session" scope, without sacrificing if possible, cleanup between tests
it will make sure to run your tests rather quickly, since session scope runs only once for testing session

maiden pawn
sinful sail
#

hello... need some help.. working with python3.12, (venv) with a simple assert (assert 5 == 5) I always get collected 0 items and (no tests ran in 0.02s)

#

any idea how to solve it?

dreamy bough
# sinful sail https://pasteboard.co/VQr5gASUrWZJ.jpg

@sinful sail I think youโ€™re missing fundamental things about setting up Pytest and writing unit tests. How do you name test methods? Proper names for tests? I think pytest is looking for tests in โ€œtestsโ€ folder which you already have based on the screenshot you provided, but unable to find it.

ember maple
pearl cliff
# dreamy bough When do you use the โ€œpatchโ€ method and when should you use the โ€œMockโ€ or โ€œMagicM...

Mock is just an object that can behave pretty much however you want it to, depending on how it's configured. patch injects a Mock somewhere. a lot of the time when people talk about mocking as a testing strategy, they really are talking about patching something to replace it with a mock.

see https://www.youtube.com/watch?v=ww1UsGZV8fQ

Speaker: Lisa Roach

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

โ–ถ Play video
sinful sail
sinful sail
dreamy bough
pearl cliff
#

one thing to note @sinful sail @dreamy bough is that you can inject any object with patch. the default is a Mock but it doesn't need to be, it can be anything

sacred depot
#

Hello everyone... I have a "problem" running a TestCase using ddt -- namely, this test:

#
    @data(
        [ True, 1, 0 ],
        [ False, 0, 1 ]
    )
    @unpack
    def test_indicator_status_calls_correct_method(self, blinkerActive,
        activeInvocations, inactiveInvocations):
        state = self.state
        when(self.context).isBlinkerRightOn().thenReturn(blinkerActive)
        when(state).handleIndicatorActive()
        when(state).handleIndicatorNotActive()
        when(state).action().thenCallOriginalImplementation()
        state.action()
        verify(state, times=activeInvocations).handleIndicatorActive()
        verify(state, times=inactiveInvocations).handleIndicatorNotActive()```
#

If I run it within the context of the whole test class, it runs OK

#

But if I try and run this test only, it fails by not finding the test name; note that I run IDEA.

#

The error message is: ERROR: not found: </path/to/the/python file here -- placeholder>::MyTestCase::test_indicator_status_calls_correct_method

#

Indeed however, when I run the whole suit, different method names are generated

#

(namely, test_inidcator_status_calls_correct_method_1__True__1__0_ for the first data set and you can guess for the second one)

#

The class itself has been annotated with @ddt

#

Is there a way that I can run this test individually with all its parameters?

#

Also, I know this code looks waaayy too much like Java, this is where I come from; I'll "unjavaify it" later when I get more familiar with Python as a whole

ember maple
sacred depot
#

Ah err

#

OK, so I need to read on that

#

Thanks for the pointer!

ember maple
#

As far as I am aware DDT makes it impossible for pytest to select groups of tests due to magically creating methods

I strongly advise to drop it when using pytest

sacred depot
#

But since pytest has it natively, I'd better use it

ember maple
#

Pytest has fixtures for dependency injection and parametrize for test parameter sets

sacred depot
#

(like the dependsOn attribute of TestNG's @Test)

ember maple
#

Dependency injection is about the resources a test may need

sacred depot
sacred depot
ember maple
sacred depot
#

OK

ember maple
#

I recommend running through a few tutorials to get a feel

sacred depot
#

That's what I'll do... First goal is to rip ddt, second is to actually use pytest for mocking... Right now I use mockito since this is what I use in Java and I'm very familiar with it

#

But I've been given the ear that "it does not look like pyhton at all" :p

ember maple
#

Personally I try to avoid mocking and patching whenever possible, it's very fragile when overdoing and its very easy to make tests that lie and sabotage refactoring with it

sacred depot
#

Ultimately it's always the same, isn't it? Write code that is obvious, the rest should come :p

ember maple
sacred depot
#

(and it still happens from time to time)

#

I'm sure I'll manage to botch designs in completely new ways in Python :p

ember maple
#

The bugger likes to truly shine in face of changes requirements or shocking enlightenments

sacred depot
#

sigh I need to rewrite the whole test :(

#

(test class)

#

OK, I don't get it

#
    @pytest.mark.parametrize(
        "blinkerActive,activeInvocations,inactiveInvocations",
        [
            (True, 1, 0), (False, 0, 1)
        ]
    )
    def test_indicator_status_calls_correct_method(self, blinkerActive,
        activeInvocations, inactiveInvocations):
    # test code here
#

When I run the test, it shows this: TypeError: MyTestCase.test_indicator_status_calls_correct_method() missing 3 required positional arguments: 'blinkerActive', 'activeInvocations', and 'inactiveInvocations'

#

Does it have to do with the test class inheriting unittest.TestCase?

#

Oh no... I think I understand

#

It's not pytest throwing this error, it's unittest

ember maple
#

Unittest subclasses don't support parameters in pytest

#

Unittest support in pytest is primarily to support running legacy tests

sacred depot
#

WIll that take into account the setUp and tearDown methods?

#

(funnily enough, most tests are written as unittest, but the test runner is pytest...

sacred depot
ember maple
#

There's unit method's and fixtures,I strongly recommend fixtures

sacred depot
#

I think I see how I can use them to emulate setUp() but for tearDown(), I have trouble finding what I want

#

Unless, uh... Maybe in fact I don't need the tearDown() here since all it does right now is call Mockito's .unStub()

#

Err, unstub

ember maple
#

The teardown is after the yield in a fixture

sacred depot
#

Ah, yield... This keyword I have a lot of trouble wrapping my head around at the moment :p

ember maple
#

It takes a bit to wrap ones Head around them

#

A yield statement Turns a normal function into an iterator, each iteration walking to the next yield statement

Pytest fixture definitions take advantage of that

By using yield to pass the value outside,the cleanup can happen when control is returned to the function

sacred depot
#

So, IIUC, you can yield x, do something, yield y, do something else and so on?

ember maple
#

Not in fixture

After all they are supposed to give out a value

#

So its setup; yield value; teardown

river pilot
#

Like many other things in "test world", the use of yield here is a bit quirky.

proud nebula
#

Same as @contextmanager though

river pilot
#

yes, there are other quirky uses.

proud nebula
#

To me this just seems like a common use for yield now.

river pilot
#

maybe there are many things that work like this. For someone new to yield, it can be confusing: "why am I using yield if there's only one thing produced?"

proud nebula
#

Maybe part of the issue is the lack of multiline anonymous functions.

river pilot
#

how would a multi-line lambda change things?

proud nebula
proud nebula
#

The yield syntax has the advantage of a common scope though, which anonymous multiline functions wouldn't.. ๐Ÿคทโ€โ™‚๏ธ

hexed cloak
#

yield syntax supports with

#

You'd have to manually drive context managers with two inline functions

proud nebula
#

true true... there are many advantages to using yield

sacred depot
#

All of you are currently speaking Chinese as far as I'm concerned :p

hexed cloak
#

Then there's v = yield w

dense bough
#

Mm. Making use of that can be a bit of a pain.

hexed cloak
#

I've not seen it really except in low level async frameworks and David Beazley magic

#

And even then it's return (yield from v)

dense bough
#

I tried to use it for some parsing. Kinda regretted it.

river pilot
river pilot
hexed cloak
proud nebula
#

I have a vague memory of using it at some point, but I can't remember when.

river pilot
#

(though I haven't looked at it recently)

hexed cloak
#

The third presentation

hexed cloak
river pilot
#

I like that.

hexed cloak
river pilot
#

that is good to see

sacred depot
#

For Java devs at least, I say this is a must read -- and it does talk a lot about the "way of testing", just as you seem to do in your presentation

#

And one thing I will have to get used to with pytest is that it does not need classes -- however your test files must be named appropriately

#

Which means that if you don't use a class for your test, then you cannot have a strict equivalent of setUp() and tearDown()

#

Hence fixtures

sacred depot
#

It's quite an opposite philosophy to TestNG in many senses

#

It (TestNG, I mean) doesn't even care what your test methods are named as long as they are annotated with @Test :p

#

Wait... try has else?? Uh...

viscid basalt
dreamy bough
#

I learned testing first with N-Unit. Then I used MS-Test, PyTest and Unittest module in Python.
I find it better to just focus on concepts instead of language focus features. Youโ€™re doing the same thing basically with different tools.

sacred depot
viscid basalt
#

You don't catch an exception from the else pithink

#

That makes semantic difference

sacred depot
#

Another thing I'll have learned today

proud nebula
#

As a rule of thumb you want to keep your try blocks small.

sacred depot
proud nebula
#

Swift has a very different syntax for try/except that makes it clearer what can happen. It's a bit annoying in the beginning but it's also a lot more solid.

sacred depot
#

OK, with pytest.raise() <-- I love that construct

#

In Java, doing this is a little awkward

#

@river pilot I thank you a LOT for the link you sent me; short and to the point

river pilot
sacred depot
#

sigh now tox is the problem

#

Why do I have a feeling that "tox" is a shorthand for "TO eXecutable"?

hexed cloak
river pilot
sacred depot
#

But now I realise that I want "poetry build"

hexed cloak
#

You can use tox with poetry

sacred depot
#

But that does not generate what I want either... I'll have to ask the project owner who is currently unavailable

#

But this has nothing to do with unit testing anyway, I wonder why I even talked about that here -- sorry

hexed cloak
#

tox is testing related

#

I consider large complex functional tests in scope for this channel

sacred depot
#

OK, well, I'll give it a try, but first of all I should explain my environment

#

I run Win11, IDEA (community edition on this PC) latest version, Python 3.11 SDK, the project uses tox and poetry

#

I've looked up the link but no luck so far

#

Also, the project uses git -- I've tried and git grep console_script and git grep gui_script but both didn't find a match

#

Basically, at this point I'm stuck

#

But I believe I should really be using PyCharm...

#

(FWIW this is not my development rig; my development rig runs Linux and has IDEA's paid version)

river pilot
sacred depot
river pilot
#

(also, i have no idea how IDEA works, or what other steps it might need from you)

sacred depot
#

pycharm throws the same error so at least it's "consistent"

sacred depot
#

(well, with vim it's easy, so there is that)

#

http://pastie.org/p/77Cr27LCLxzKYSzlc50Ev0 <-- that's the full output of the "py311" part (which I suppose stands for the python version I use) but there are two other parts to the tox output (isort and pylint) which show the same error exactly

#

Oh dammit, I pasted the unedited part... Well, that's too late

#

Well, I managed to make poetry build run

river pilot
sacred depot
#

Yep

#

Private on github, and not mine, so I resent having pasted that :(

river pilot
#

fwiw, i don't see what is secret in there.

#

seems like optishift has a problem.

#

but i'm not sure exactly where the error is from, and I don't use poetry.

sacred depot
#

Well, I could build the package... So I can run my code at least

#

I know it works as I intend it to do since I tested it :p

#

FWIW it's a plugin for ETS2

river pilot
#

idk what ETS2 is, but that doesn't matter. It will be hard to help untangle this without the code itself.

sacred depot
river pilot
sacred depot
#

(and now we're really veering off topic)

sacred depot
#

Yay, mistake in the design stage...

brave obsidian
#

Hey i have the following fastapi endpoint:

@router.post('/login', include_in_schema=False)
async def login(request: Annotated[OAuth2PasswordRequestForm, Depends()],
                db: Annotated[Session, Depends(get_db)]):
    user = db.query(DbUsers).filter(DbUsers.username == request.username).first()
    if not user:
        raise HTTPException(
            status_code=404,
            detail='Invalid username'
        )
    if not Hash.verify(user.password, request.password):
        raise HTTPException(
            status_code=404,
            detail='Incorrect password'
        )
    access_token = create_access_token(data={'username': user.username})
    return {
        'access_token': access_token,
        'token_type': 'bearer',
        'user_id': user.id,
        'username': user.username
    }```

get_db dependency:
```py
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()```

My question is how can i mock the db dependency ?
weary quarry
#

You can stand up a test database in a container while running the test. The general idea of how best to mock the db dependency is to use a db.

brave obsidian
weary quarry
#

A fantastic use for sqlite.

sacred depot
#

H2 is quite nice in this scenario too

#

But it depends on what SQL language features you use as well

proud nebula
#

Imo use the same db as in prod as far as possible.

sacred depot
proud nebula
#

Whatever "unit test" means when you're running a db. See, this is why I avoid the terms. They make no sense.

sacred depot
#

If you want to test the behaviour of your code, there is no reason to use a production db

#

KISS

proud nebula
proud nebula
#

If your prod runs on postgres, test with postgres, not sqlite.

sacred depot
proud nebula
sacred depot
#

After that, IF AND ONLY IF you use constructs specific to your DB then the first question would be to ask whether you actually need said constructs

#

If you do then you have no choice

#

But I avoid engine specific constructs for that reason

proud nebula
#

Oh sure, so do I. But again: sqlite will let you store a string in an integer field by default. Your tests can run right through that.

sacred depot
proud nebula
sacred depot
#

Well, I suppose we have different views on that matter; I fail to see how I could write code with such a blatant error, but that's probably due to my methodology when developing

#

(which is not flawless, of course, no methodology ever is)

proud nebula
#

I just picked one very clear and simple to understand issue with using sqlite

sacred depot
#

Well, try H2 then

#

It's even lighter

proud nebula
#

๐Ÿฅด

sacred depot
#

And it only does ANSI SQL too

proud nebula
#

Anyway, it seems weird to me to call it a "unit test" and it uses an entire DB engine. To me that's not a "unit test". And again, this is why I avoid the term: because it's not well defined. We could just as well be saying "floorb gnorbly tests"

proud nebula
river pilot
#

I agree that "unit" is ill-defined, and it's more helpful to think of tests on a spectrum from "tests a very small amount of code" to "tests a large amount of code".

#

whether to use the same db software: it's a trade-off: sqlite is faster and easier, but is a different dialect of SQL.

drifting sorrel
#

You could monkeypatch the get_db function, and you would probably also want to monkeypatch the create_access_token function for your test to be concidered a unit test. The tests would assert output and probably also indirectly assert the hash verification.

river pilot
#

Another option: a fake db implementation that you can inject

low torrent
#

Hi i have problem, I try write selenium tests but when use wait my button can't be clicked ๐Ÿ˜ฆ

# this work
element = driver.find_element(By.CLASS_NAME, 'login-btn')
element.click()
# this don't work
element = driver_wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'login-btn')))
element.click()

Problem starts when i try use EC for finding elements

drifting sorrel
#

Once writing a unit test like this, you will quickly notice that monkeypatching the db is painful, because of the advanced structure of it (chaining calls etc.). A simple solution is to extract the DB query into another function and monkeypatch that one. Then you only need to return the data, and not patch a complex SQLAlchemy-like object.

ember maple
viscid basalt
#

If you want to use the same underlying connection int your test and application running underneath you can override your sessionmaker's bind:

@pytest.fixture
async def session(
    _sqlalchemy_run_migrations: None,
    sqlalchemy_pytest_engine: AsyncEngine,
    async_sessionmaker: AsyncSessionmaker[AsyncSession],
) -> AsyncGenerator[AsyncSession, None]:
    async with sqlalchemy_pytest_engine.connect() as conn:
        transaction = await conn.begin()
        async_sessionmaker.configure(bind=conn)  # <-----------------------

        async with async_sessionmaker() as session:
            yield session

        if transaction.is_active:
            await transaction.rollback()
viscid basalt
teal minnow
proud nebula
pine loom
#

def prks_ownership_data(spark, batch_id, prks_file_path, dbname):
print("Spark URL " + spark.sparkContext.uiWebUrl)
prks_schema = StructType()
.add("PRO_VAL_DATE", DateType(), True)
.add("PRO_OWNERSHIP_LEVEL", IntegerType(), True)
.add("PRO_ACCOUNT_ALIAS", StringType(), True)
.add("PRO_PRKS_FUND_ALIAS", StringType(), True)
.add("PRO_PMIS_FUND_ALIAS", StringType(), True)
.add("PRO_COMP_LINK_ALIAS", StringType(), True)
.add("PRO_MARKET_VALUE_BASE", DecimalType(38, 10), True)
.add("PRO_OWNERSHIP_PERCENTAGE", DecimalType(23, 15), True)
.add("PRO_OWNERSHIP_PERCENTAGE_CUST", DecimalType(23, 15), True)
.add("PRO_MARKET_VALUE_USD", DecimalType(28, 10), True)
.add("PRO_PARENT_PRKS_FUND_ALIAS", StringType(), True)
.add("SECURITIES_LENDING_STATUS_FLAG", StringType(), True)
.add("CUSTODY_ALIAS_OF_PMIS_ALIAS", StringType(), True)
.add("PROXY_ACCT_NSRD_FUND_ALIAS", StringType(), True)
.add("PRKS_OWNERSHIP_FLAG", StringType(), True) \

    prks_owndership_df = spark.read.csv(prks_file_path, header=True, schema=prks_schema)
    prks_owndership_df = prks_owndership_df.withColumn("BATCH_BASE_ID", f.lit(batch_id).cast(LongType()))
    prks_stage_table = '{DBNAME}.IVC_PRKS_OWNERSHIP'.format(DBNAME=dbname)
    prks_partition_cols = ["PRO_VAL_DATE","BATCH_BASE_ID"]
    prks_owndership_df.write.mode("append") \
            .format("delta") \
            .partitionBy(prks_partition_cols) \
            .saveAsTable(prks_stage_table)
pine loom
sacred depot
teal minnow
#

This should pass:

def test_prks_ownership_data():
    try:
        result = prks_ownership_data("spark", 1, "./sparks", "sparks_db")
    except:
        pass
    assert True
maiden pawn
#

Clip from, LOTR: The Fellowship of the Ring (2001)
"You Shall Not Pass!" (short version)
For, Jerry Sullivan


Under Section 107 of the Copyright Act 1976, allowance is made for fair use for purposes such as criticism, comment, news reporting, teaching, scholarship, and research. Fair use is a use permitted by copyright statute that might...

โ–ถ Play video
river pilot
sacred depot
#

He obviously was... But I'm learning some things from such code, given my poor Python knowledge so far

#

"poor" is an understatement

#

"piss poor" is more accurate

proud nebula
#

Not obvious at all. People write worse code than that 100% seriously all the time.

languid sentinel
#

does assert None will fail test?

ember maple
pine loom
viscid basalt
#

๐Ÿ˜‰