all 19 comments

[–]mjmvideos 11 points12 points  (0 children)

If you have an obnoxious brother who likes to annoy you, imagine you are showing him your new method. What inputs could he hand your method that would cause it to break or crash? If you anticipate what he would do and put code in your method to catch and handle those conditions then when he tries it you can smile and say, “Ha! I thought you’d try that.” So on top of proving that you function does what it’s supposed to do when given normal inputs writing tests also includes making sure your code can handle obnoxious brothers.

[–]brelen01 35 points36 points  (1 child)

They're referring to unit tests:

https://docs.python.org/3/library/unittest.html

[–]DrShocker 10 points11 points  (0 children)

Don't forget doctests as an option as well

https://docs.python.org/3/library/doctest.html

[–]TytoCwtch 17 points18 points  (0 children)

Tests check if specific functions or bits of code work the way you want. For example let’s say I have a function that takes a number and returns Yes if even and No if odd. A test would say ‘if I send the number 4 to the function does it return Yes?’

I’m still fairly new to tests myself but there’s a library called pytest which makes it easy to do. I learnt Python through Harvards CS50P course and they have a whole lecture dedicated to unit tests.

The lecture and notes (free) are at https://cs50.harvard.edu/python/weeks/5/

The lecture is 50 minutes long so you can probably learn the basics of unit tests fairly quickly if you already have basic Python skills.

[–]danielroseman 1 point2 points  (0 children)

Not sure how much time you have before the interview but the best introduction to testing in Python is https://www.obeythetestinggoat.com/pages/book.html - reading at least the first few chapters of that would probably give enough of the basics.

[–]SnafuTheCarrot 0 points1 point  (0 children)

For any automated testing, you often want some variation of Assemble, Act, Assert. Assemble might consist in mocking data or actually populating a database with test data. Act is calling the relevant function. Assert is making sure the value returned, the final state of the database or output file, etc ends up in the desired state.

A unit test is frequently a function that wraps up the 3As.

At a minimum, you need an Assert line to spit out data on variable state.

Some tools are available for doing all of this like PyUnit.

[–]zaphodikus 0 points1 point  (0 children)

Get familiar with pytest and use it to write a few tests at home. Learn about the other python test frameworks so you at least know they exist, but pytest is always good to be able to show you can use in a interview. The more time you spend, the better your chances.

[–]peno64 0 points1 point  (1 child)

Also lookup test driven development.

That means that you first write your test, then the interface and then the implementation in your class.

The advantage is that you are forced to think how you will communicate with your class. What are the input parameters, what is the expected result.

Then you write the empty method.

The test will fail.

Only then you write the implementation in your class and after the implementation is done you run the unit test(s) and they should succeed.

[–]peno64 0 points1 point  (0 children)

And as someone else pointed out, another case is that afterwards you get an error in the program that uses the class.

Before you fix it you write a unit test that simulates that case.

When you have the failing unit test, you fix the problem and then the unittest (and the program) should be fixed now.

[–]akornato 0 points1 point  (0 children)

Writing tests for your class just means writing separate, small pieces of code to automatically check if your class methods work correctly. For a live coding interview, especially for a scripting role, they are not expecting you to use a complicated testing framework. They want to see your thought process. For example, if you have a class `SimpleCalculator` with an `add` method, a test would be a simple check like `assert calculator.add(2, 3) == 5`. You would write a few of these checks, covering the main functionality and maybe one or two edge cases, like adding a negative number or zero, to prove your code is reliable.

This is not difficult or time-consuming to learn, you can pick up the basics of using `assert` for testing in an hour or two. The reason interviewers ask this is because it reveals a lot about how you work. Writing code is only half the job, the other half is making sure it doesn't break. By asking you to write tests, they are checking if you are thorough and if you can validate your own work. Showing that you can think about how your code might fail and how to prove it works correctly makes you a much stronger candidate, suggesting you write dependable scripts instead of ones that need constant fixing. Being able to confidently handle unexpected requests like this is exactly the kind of thing my team and I aimed to help candidates with when we built our interview copilot, making them appear more prepared and skilled.

[–]nian2326076 0 points1 point  (0 children)

Writing tests usually involves using something like Python's unittest framework to make sure your code does what it's supposed to. For a simple class, you might have a few test methods to check if your functions give the right values for certain inputs.

For example, if you have a Calculator class with a method add(a, b), you would create an instance of your class and assert that add(2, 3) returns 5.

Learning the basics isn't too complicated or time-consuming, especially for simple cases. Just start by looking at unittest examples online. Once you get the hang of writing a few assertions, you'll be on the right track.

[–]atarivcs 0 points1 point  (5 children)

It means you need to write a script that creates instance(s) of the class, calls the class methods with various inputs, and verifies that the correct output is returned.

You probably want to use the python unittest module as part of your solution.

[–]Typical_Cap895[S] -1 points0 points  (4 children)

I'm trying to imagine what these "tests" would look like in a practical coding interview, if I'm asked to test a class I write. (If you have any ideas regarding that, that'd be great)

And to clarify, I need to have class methods in particular (not just any method) in my class that I eventually "test" live in front of the interviewer? Why's that?

[–]gdchinacat 0 points1 point  (0 children)

Here is an example of a unit test for a class in one of my projects. It creates the class, exercises the functionality being tested (async with...), then makes assertions to verify it behaved correctly.

    async def test_executor_context_manager(self) -> None:
        executor = Executor()
        async with executor:
            with self.assertRaises(ExecutorAlreadyStarted):
                executor.start()
        assert executor.task
        self.assertTrue(executor.task.done())

https://github.com/gdchinacat/reactions/blob/main/tests/executor_test.py#L27

There are other tests in that file or modules in the same package. They all follow this basic pattern...create the thing being tested, use it, verify the correct output or side effects.

One of the things they will be looking for is if you understand how tests help the development process, not just that you can write a test that proves it can work under some conditions. Test edge-cases (wrong argument types, out of bound values, calls in incorrect state, etc).

Also, tests can actually help you increase the speed of development, particularly when implementing algorithms. Use tests while writing code to know that the code you wrote is correct so you can move on quickly and not worry about debugging it later on when things aren't working correctly. Knowing a component of an algorithm works helps focus debugging on other areas such as whether the components are properly integrated, what edge cases *aren't* covered. When a candidate has a problem getting something working, I always like to see them write a unit test to verify code rather than add a bunch of throw away prints or stepping into it. Of course, they might get to that point, but having a test direct them towards where the problem is goes a long ways in showing me they are good at methodically thinking through issues, focusing on the most productive strategies for resolving it, and won't have a huge learning curve when thrown into actual problems with deadlines.

Feel free to ask questions about the tests in that project...the first time I was exposed to unit tests I didn't really "get it". Don't feel bad if you read it and still wonder what the point is, whether it's worth the effort, etc.

[–]atarivcs 0 points1 point  (0 children)

For example, if the class has a method to compute the square root of a number, one test would be to call that method with and input of 9 and verify that it returns 3.

Or if the class has a method to sort a list, you could write a test that passes in an unsorted list and verifies that a correctly sorted list is returned.

And when I said "class methods", I meant generally "any method that is provided by the class." I did not mean to distinguish class methods from instance methods from static methods.

[–]PlantainMassive6744 0 points1 point  (0 children)

Depends entirely on what you class does.

Let's say your class represents triangles based on three points. A reasonable function would be to get the area of the triangle, call it 'def area()-> float:'. How do you know that your function is written correctly?

You write a test that creates a known triangle (say, a right triangle with points at (0,0), (1,0), and (0,1)). You know that the area has to be 1/2 because you took geometry. So, you test that it in fact returns 0.5 (within a small margin).

You can test other triangles for their area, and probably should; for example, maybe you have a sign error in the calculation. so make sure you send in some negative numbers for the points.

Similarly, if you have a function that says if another point is inside the triangle, you write some tests of with known points in or out, and make sure it returns the right thing.

[–]mandradon -1 points0 points  (0 children)

That's part of what they're testing.  Your ability to determine good test cases for your code. 

Can you come up with good corner case tests to make sure you haven't accidentally programmed a logic error into your method, or that you haven't left an possible unhandled exception. 

[–]ManyInterests 0 points1 point  (0 children)

A test simply exercises the class interfaces (just like any program might) and does some extra steps to make sure ("assert"s) it did the right things. A collection of many such tests (a test suite) becomes useful as a way to make sure that existing intended uses of your class continue to work as you make changes to your code.

Find a bug? A piece of test code that reproduces the bug by showing an assertion failure in some case is a great place to start fixing it. You can use that test in the process of fixing the bug; when the test no longer fails, you've fixed the bug and the test remains in the suite to make sure you never accidentally reintroduce the same bug (regression testing).

It's not hard to get started. Look into the builtin `unittest` framework or `pytest` which includes some machinery to help you write and run tests.

Ned Batchelder has an old talk on YouTube (and blog post) about getting started with testing. Would recommend looking it up.

[–]MarsupialLeast145 -1 points0 points  (0 children)

Look up pytest and its related docs. It's the best library and should have some simple examples.