Python Testing: A Philosophy

Python Testing: A Philosophy

It’s been a bit since I’ve been here, but there really haven’t been many updates in regards to new and exciting topics in the working realm for me. One thing that I have wanted to cover is Python Testing. Not necessarily how to do it, but the motivation behind writing good tests. Am I an expert in test writing? No. Have I been learning what makes one test better than another? Yes (hopefully). Here’s a few thoughts I have regarding testing.

Be very explicit with naming your test function. When your tests run you’ll see the names and if they’re all called testX, that’s not super helpful. Try something like test_blue_cat_food_bowl_half_filled_hungry_cat. Or whatever. Even if you don’t love the name I made, you know you’re testing how the blue cat food does with a hungry cat and a half full bowl. Use docstrings to then describe in more detail what data you’re setting up for the test and what you’re calculating and expected results.

# not using decorators or anything here for this illustration
def test_blue_cat_food_bowl_half_filled_hungry_cat():
    """
    Tests that the cat will eat the cat food in the bowl.
    One bowl, blue food, one cat, cat's hunger level is hungry
    """

Have your actual testing test only one idea at a time. Say you also need to test to make sure you have the right breed of cat. Make a separate test for that. Sure you could go ahead and test for it in this test, but that’s not within the scope of your function name. Plus if that part of your code breaks in regards to the cat breed, you’re going to have to update more than just that one test that deals with checking it.

Ensure you’re data is set up correctly. Your test may pass, but you may accidentally have something in your test assuming that you’re always being given a full cat because that’s the default cat setting in your factory or whatever. Make sure that anything you’re testing, you explicitly define the test values so you’re not getting false positives.

Test the small things first and then work up to more complex testing. You may want to just set up your one test that is supposed to test everything is summed and converted correctly and just figure that it will pick up the small things. I’ve found this is not the best way to start off. Writing lots of smaller, specific tests to test out all the smaller building blocks of the larger bits of code that use those blocks has proved to be way more effective. It’s also a plus that if you know all your simple cases work and a more complex test fails, then you can narrow down what is going wrong a bit easier too. Which also goes back to my earlier point that if something breaks then you are able to fix that little bit way easier than in your mega test.

Those are the big things that I have learned are super important with setting up and writing sensible tests. It’s pretty easy to find out how to write a test syntactically, but unless I’m just lazy with my Google searching, it’s a bit more difficult to find good references on what makes a good test. Anyhoo, let me know if you have any other testing wisdom!

-Rachel

Render JavaScript Within Flask

Render JavaScript Within Flask

So a while ago I wanted to use some JavaScript to do some auto-filtering on a dropdown box I had in Flask. However, this wasn’t a static JavaScript file, I needed some dynamic-ness based on some other functionality and couldn’t just serve up a static JavaScript file. What I found was that there weren’t a lot of good examples for what I wanted to accomplish. Most of the examples you see are html files with JavaScript in the script tags. Which is cool, I just didn’t want to do it that way.

First, write up your JavaScript and stick it in with your templates. I had to use $.getJSON(), so the dynamic part of my JavaScript within Flask looked like below. Basically it is querying my database and grabbing applicable data based on a previous user selection. I’m doing the grabbing with Flask and the making with JavaScript. If that makes sense. And please pardon my lack of technical JavaScript terminology.

// your_javascript.js
$.getJSON("{{ url_for('main._get_stuff') }}", send, function(data) {
            data.forEach(function(item) {
                dropdown.foo.append(
                    $('<option>', {
                        value: item[0],
                        text: item[1]
                    })
                );
            });
            dropdown.foo.removeAttr('disabled');
        });

Then you’ll want to render your JavaScript where your routes live. Mine looks similar to this:

@main.route('/some_route_you_chose')
def render_that_javascript():
    return render_template('your_javascript.js')

In the template you want your JavaScript in, put the url_for your rendered JavaScript in your block for scripts:

{% block scripts %}
<script src="{{ url_for('main.some_route_you_chose') }}"></script>
{% endblock %}

There you go. Flask rendering JavaScript that needed some dynamic content. Hopefully if you were trying to figure this out yourself you found it helpful. More next time!

-Rachel

When One Liners Make Sense

When One Liners Make Sense

Have you ever written a little one or two line snippet of code you were super proud because it was oh so short and sneaky and clever? But then, like a month (or 20 mins) later, you have to go back to it and you have no idea what that stinker’s actually doing? Yeah, me neither.

A close up of a long haired tabby cat staring directly at the viewer
Keep Calvin happy! Write clean code!

I have some thoughts on little clever bits of code. First of all, they’re cool. Yay for figuring out how to compress say 15 lines into two! Second of all, they can drive me nuts when having to go back to review old code. Especially if it contains regex (shakes fist at regex). I also think that there are sometimes places that are more suited for the clever bits than others. Let me explain . . .

I think that if you’re deliberately trying to condense your work down into fewer lines for the sole sake of fewer lines, you’re in danger of losing the overall clarity of you code. And in the long run, that’s going to make your code more difficult to maintain by you and others.

Now when do I think that a cute one-liner is appropriate? I like to use them when doing so doesn’t distract from the overall idea of the function or method I’m writing. It’s like a mini subroutine (but not) that I don’t have to do any extra work for. For example:

# x is a datetime field
sorted(my_list, key=lambda x:x[1], reverse=True)

I could have written a helper function that went through my list and sorted them by date then reversed it, but it turned out to be much more concise to use a lambda function within the built-in sorted() function. It also made way more sense to just use a built in function rather than writing my own.

Another example:

# _ can be used in python editor to reference whatever 
# was on the previous line. Fun, right?
>>> [1, 23, 1, 45, 5, 9]
[1, 23, 1, 45, 5, 9]
>>> [s for s in _ if s > 10]
[23, 45]

# The following is equivalent to above 
# but in more lines.
foo = [1, 23, 1, 45, 5, 9]
foo2 = []
>>> for each in foo:
...     if each > 10:
...         foo2.append(each)
...
>>> foo2
[23, 45]

But if that logic was more complex and my one liner started getting long and I had to start line wrapping it to fit? Nope, that’s going to be way more difficult to read and understand in the long run. (That also goes against the PEP 8 Style Guide. I like to stay within the 72 character line limit, thank you.) Anyone coming after you that has to do anything with that code (including you) is just going to want to whack you over the head with a boot. Just write out some loops, man.

Have fun finding clever ways of coding!

-Rachel