Having a robust test suite for your Python web app
Tanay PrabhuDesai (~tanay) |
One of the first projects that I worked in the industry was in Flask. This talk is based on my experiences in the project with respect to the test suite and the different things that I learned in that. On the bases of those learnings, I started my own open source project on Github and enhanced on those ideas on how all the things necessary for testing are done. This is based on Flask as the web framework and all the ideas are implemented in it. The topics it covers are those things that you can do to achieve a robust set of tests in your code.
Some of the tricks and suggestions mentioned in this talk will pertain to web applications developed using Flask microframework. It might or might not work with other frameworks out there. The code snippets shown on the slides and the live demo (if possible) will be of Flask.
Outline of the talk
Architecture of the application explains the simple architecture of the application which will make it easy to build all the concepts of testing on top of it. This will consist of the basic description of the layers in a typical web application like the database layer, services, and controllers.
Tests at various layers will highlight the different tests at different layers, this also consists of which test are more important than which other tests and why. This will consist of different types of tests like unit tests, repo tests, HTTP tests etc.
TDD top to bottom through the layers you can go from top to down when doing TDD by first starting to write your first test at an API level looking at yourself as a consumer of the API that you are writing the test for. This can happen with starting writing the tests for HTTP REST endpoint that is exposed and then going deep into the layers.
Unit testing and the evil of mocking will talk about how unit tests are written in our industry and how tests doubles are overused which leads to various problems with respect to the wholeness of the part tested by the test.
Speeding up test execution sometimes the reason people avoid running tests is that they take a very long time to run. One of the main things in test-driven development is that we should be able to run tests as frequently as possible, for that the tests need to be fast.
Predictable test tests can become indeterminate, i.e. we can't predict whether a test will either pass or fail. Tests should always pass when they are supposed to pass and should fail always when they are supposed to. We can perform dependency injection for the objects which have random behaviour.
Test ice-cream cone vs test pyramid vs test cylinder, where to focus in our industry there is too much of focus on writing a lot of unit tests and a lesser number of tests as you go up the layers of the architecture. The argument usually is that tests get slower as you go up. What if this is not that much of an issue anymore? It is good if all scenarios are tested end to end.
Pushing code coverage towards 100% forcing your CI tests to increase the code coverage slowly and gradually and never let the code coverage drop. We can have things like forcing the CI to fail in case if the code coverage drops.
Although most of the things are implemented in Flask, it is not necessary to know it, although it is very much recommended to know some web framework or having some knowledge of web app programming.
The repository where I have implemented concepts related to this talk https://github.com/tanayseven/http_quiz
Contents for the presentation for the talk https://github.com/tanayseven/pycon_2018_python_web_app_test
A passionate developer with Python as his primary language. Have worked with Flask in the industry in the past. Passionate about testing and writing the code in a way that is very clean and maintainable. A strong believer in TDD and massive test coverage.