3 ms·
>Well, if making sure to include automated testing for APIs and error handling is junior, I look forward to staying a junior engineer for my whole life. I don't
by formulathree 3y ago
>Well, if making sure to include automated testing for APIs and error handling is junior, I look forward to staying a junior engineer for my whole life. I don't think I'd submit a take home coding test without tests.
Error handling is already done by the framework. If you want explicit handles that's just busy work. Most python crashes involve traceback sent to stderr telling you what error occured and returns a 500. which is exactly the kind of handling I want. I'd just be replicating the framework code with the same logic everywhere if I did what you mentioned.
I'll give you credit for the unit tests. There's only 2 unit testable functions in the entire code and it's all in utils.py. Practically speaking only the random path generator is worth any sort of automation testing, and the http request callee is io, so not unit testable. Integration tests are raw overkill on takehomes. Manipulating docker compose in test code is just overboard.
Are you currently a junior? If you are then the insight you should eventually achieve is that unit tests for web application servers is not as important as you currently think.
This is because web servers are primarily io based applications. There's overall not much pure logic you can abstract to unit tests.
Pure logic rarely has errors as it doesn't deal with state. You will find that unit tests become a lot of extra busy work. If your pure logic minimizes mutations and you properly use typing and use functional code your error rate will drop to the point where you mostly write unit tests for other people. Writing it for your own code is essentially writing thousands of lines only to find it didn't catch a single error. It's still good to have unit tests but the cost benefit analysis becomes out of whack the majority of the time.
Did you know Edward Dijkstra was famously against testing? He promoted a different sort of art that would guarantee your code worked 100 percent of the time for all cases. Say I had a unit test: assert(add(100, 1) 101). That only covers one test case out of trillions of possible errors. His method would cover the entire spectrum of possible cases without a single test.
Basically a good coder should be hybridized in his approach. Code in a way that uses Dijkstra's philosophy such that the need for tests are minimized then write the tests you need without excessive focus on it because you should know that your tests are only covering a fraction of possible test cases anyway.
Not all engineers discover this method or even take the time to internalize and utilize it. Thus their code often ends up being error prone enough to justify unit testing or test driven development. Many super senior engineers don't even know about this. The staff position is more of a political title that has to do with leadership and architectural planning.
Anyway, unique to backend engineering... Integration tests are where most errors occur. It's where state is mutated and where race conditions, dead lock and where most compute logic is directed towards. It's 100x more important to focus on testing at the integration level.
The problem here though is, like I said, the infra around integration tests is huge. So often it doesn't get done and you see a bunch of companies just end up using zero integration tests and some small set of unit tests that are mostly inconsequential.
>but I certainly am not proud to show anyone untested code -- it is enshrined in my mind as a measure of quality
Deshrine this if you can. There are many techniques outside of this single methodology of testing for writing good code.
For example, have you heard of Idris? Idris is a language where you can use the type system to prove the program is correct. Test cases only cover correctness for a specific case. For Idris you can write a sorting algorithm and literally prove it to be correct for all cases without writing a single test.
I'm not a complete adherent to total proof based methodologies. As mentioned previously I follow a hybrid approach such that my need for testing is minimized. Remember Enshrining any concept blinds you from alternative paths.
I view excessive unit tests as a crutch. Any programmer who actually relies on unit tests during programming to catch a lot of his own errors actually imo has a flawed model inside his head on how to compose logic while minimizing errors.
The experience of a web application programmer with a good model of logic composition in his head is that the unit tests should be passing asserts the overwhelming majority of the time.
If you are consistently using it to pick out hidden logic errors in your code it sort of works from a practical standpoint but you're not on the ideal path.
Unit tests are good, don't get me wrong but Enshrining the concept and relying on it, is a crutch.
>Everyone knows they should write tests... But do you actually? Because one thing is definitely harder/takes more discipline than the other.
They only do it if the entire team does it. Otherwise the majority of people don't do it in the face of looming deadlines. Unit tests are usually baked into dev culture, if standards require it they'll do it. Thus logically if unit testing is required it's not really that important to measure this aspect during the interview as they will write it regardless of whether or not they do it in the interview.
- hardwaresofton 3y ago> Error handling is already done by the framework. ... You literally had a bug in your code that would have been caught with testing, and it did not have to do with the logic but with input sanitization, which has to do with your integration with what the framework provided you. I am not advocating for unit tests, I was advocating for any tests at all, in the code sample. I already said that the highest value tests in my mind are E2E tests. The ones that make sure your code does what it says it does, in as black-box a way as possible. Also, I want to note that the logic you're applying works best with languages with strong type systems, not Python. I don't know what your point was on not testing is (were you trying to allude to property testing/fuzzing?), but here in the real world, tests are good for testing edge cases and preventing regressions. I am only comfortable skipping tests completely in languages with strong, expressive type-systems -- Typescript, Rust and Haskell. Even then, I still make sure to write regression tests and think of what can go wrong. Again, YOU think that the difficulty to writing integration tests is huge, and that's because you don't do it a lot. To me that's a liability, not something I want to adopt -- the faster I can write tests and prevent regressions, the better code I am able to write, the easier it is to integrate my code and have confidence that changes don't break existing functionality. > Deshrine this if you can. There are many techniques outside of this single methodology of testing for writing good code. Absolutely not -- no matter how strong your type system is, it will bend and break during contact with the real world. E2E tests, regression tests and the like are crucial for good engineering. > For example, have you heard of Idris? Idris is a language where you can use the type system to prove the program is correct. Test cases only cover correctness for a specific case. For Idris you can write a sorting algorithm and literally prove it to be correct for all cases without writing a single test. > > I'm not a complete adherent to total proof based methodologies. As mentioned previously I follow a hybrid approach such that my need for testing is minimized. Remember Enshrining any concept blinds you from alternative paths. > > I view excessive unit tests as a crutch. Any programmer who actually relies on unit tests during programming to catch a lot of his own errors actually imo has a flawed model inside his head on how to compose logic while minimizing errors. > > The experience of a web application programmer with a good model of logic composition in his head is that the unit tests should be passing asserts the overwhelming majority of the time. > > If you are consistently using it to pick out hidden logic errors in your code it sort of works from a practical standpoint but you're not on the ideal path. > > Unit tests are good, don't get me wrong but Enshrining the concept and relying on it, is a crutch. You seem to be battling one heck of a strawman here. I have not said that you should write excessive unit tests. I said that you should have at least any tests, and that I find the most value in E2E tests. Also, Idris is basically Haskell w/ dependent types, but what you're saying about it is full of half-truths. You cannot use the type system to prove a program is correct, you use type systems to prove a program is sound. Correctness is problem dependent, input dependent, and many other things that are situation-dependent. With a strong type system, you can avoid unit tests, but only if you use that type system properly (ex. using a Natural instead of an Integer where it is appropriate). Regardless of whether you have a strong type system or not, tests (of all kinds, but especially E2E and regression) are valuable and have their place. > They only do it if the entire team does it. Otherwise the majority of people don't do it in the face of looming deadlines. Unit tests are usually baked into dev culture, if standards require it they'll do it. Thus logically if unit testing is required it's not really that important to measure this aspect during the interview as they will write it regardless of whether or not they do it in the interview. I think it's a matter of culture. Are you the person that makes time to write these/makes it part of your plan, or not? There are people who do, and people who don't.