Django has a handful of console commands to help manage and develop sites. django-rich adds color and nice formatting. In a recent release, django-rich also add nice colorized tracebacks to the Django test runner.

Transcript for episode 185 of the Test & Code Podcast

This transcript starts as an auto generated transcript.
PRs welcome if you want to help fix any errors.

Django has a handful of console commands to help manage and develop sites. Django Rich adds color and nice formatting. Super cool. In a recent release, Django Rich also adds nice colorized trace backs to the Django tab test runner. That’s what we’re talking about today.

Welcome to Test and Code.

Test and Code. Am excited to have Adam back on. Adam has been on the show a couple of times before.

We were talking about boosting your Django DX last time, and I’ll put a link in the show notes. And then we have an extra person at the end of the talk. When I was talking to Adam, he mentioned to me that it would be really cool to talk about the Django Rich Test Runner that’s coming in. So that’s what we’re talking about today. And we also have David on. So, David, welcome to the show.

Hi. Thank you very much for having me here today.

So can you tell us a little bit about who you are?

Yeah, sure. So I’ve been working with Python for the past three or four years now involved in contributing to a couple of Django projects. I am one of the maintainers of Django CRISPR Forms, which is a package that helps you render your forms in Python code.

And I am also a member of the Django Triage and review team, so I contribute regularly to Django core.

This is impressive. You mentioned before we start recording that you’ve really only been using Python for a few years. Is that true?

Yeah, I started learning as a hobby maybe three or four years ago. Now as a day job. I’m an accountant, so I feel like the biggest imposter being here today.

So an accountant and you’re a Python developer and you’re contributing to Django and even maintaining doing triage for Django issues and maintaining a package or two or three. That’s pretty cool.


Well, so we wanted to talk about start out with Django Rich and the Runner, but those are two different kind of one package. Right. But the runner has been added, is that correct?

Yes. Django Rich is a package I created actually whilst writing my book to integrate Django with Rich, which is this beautiful text formatting library for the command line. And I always had this idea to create the Test runner so that when you use Jenga’s test framework, you get nice column results. And David is the one who’s actually gone.

Well, before we talk about the runner part of it, before the runner came in, what did Django Rich give you that we didn’t have out of the box?

One key feature, really. So Django has this concept of management commands, which are a structured way of building a command that you can run within the context of your project, the command line based class that gives you Archipel reconfigured and then a way to output. And Django Rich extended that with a Rich console output. So no longer you restricted to the built in output formatting in Django, which has some polarization, but not much. You can use all the features of which things like a progress bar panels and scrollable text in whatever you like.

Oh, cool. Yeah. Everything’s been going multicolored with Rich recently, so that’s nice.

So David, how did you get involved with this project?

I was working on the Django Test Runner that’s in Core that is used to run Django’s own test suites with a view of enabling parallel running on Mac and Windows.

And while I was working on that, I was interested in Django and Rich and how we can colorize the outputs.

So I looked at Django and Rich and I shared a post on Twitter showing a look at the output that you can generate from the Unit Test Runner using Rich.

Adam commented that he had a package that was django Rich together, so I made a poor request to merge that feature into Adams package.

How long were you working on? This was a difficult project, so we.

Needed to override two or three classes within the Unit test framework and the main changes were to output the color for when a test passes or fails the test results that gave you your color of the green dots as they go along.

And we also caught the exceptions if there are and pass those to Rich’s wonderful exception handler.

And that produces the Rich trace backs which give you a much nicer output for your failed tests than the standard Unit test output. So you get a little snippet of the lines of the code where the test was failed, and also the locals.

On the GitHub repo page read me, there’s an image on there showing this and it looks great. This is cool.

And the color and the output is all from Rich. So Rich does the hard work.

We’re just passing the exception to Rich and is doing all the hard work.

Yeah, it’s really cool. One of my favorite features is also a bit hidden during the output whenever it outputs locations with the file name, colon the line number, I think. And in those terminals you can click that and it will open that file on your editor so you can go straight from the failed results to the place in the code.

It’s like command, click on the control, click on of units depending on your terminal.

So it’s like links in there.


There’s a protocol for doing them in the town.


This is under the Unit Test Runner. There’s kind of two that people use in Django that I know of. The default is Unit test and then some people use by test Django. So this would be using the Unit test version, right?

Right. Yes. I would say it’s like a way of trying to get Django’s Unit test run a bit more up to scratch with fighters for those who can’t or aren’t willing to make the effort to change.

So what are some of the differences?

Are there big gaps in functionality or is it just the look and feel of it?

Yeah, like the Unit test doesn’t have so many features built in by default. Django adds a few.

David has been helping get the parallel test running in Django, which has existed for a while, but it’s never worked on platforms that don’t support fork. So that includes Mac OS. Since Python 3.8, there is a workaround, whereas with Pythest you can install Python XDS, and that does what Django will now do in sporting processes.

Okay, so the Django test runner does parallel stuff.

Now it has done it with fork for a while, like the OS fork system, but that doesn’t work either way. Okay, yeah. So all these features Django has to add like that to try and get closer to what price has offered out of the box.

Is that with the price of Django rich, or is that built in to.

Django now that’s built into Django.

Okay, so, David, you’re contributing directly to the Django as well.

Yes, I guess I like camping rules, just want to leave the world a better place, and I enjoy doing it.

That’s nice. That’s the kind of attitude we need a lot of people to have for us to push all these nice packages forward.

One of the questions that we brought up was why have this Django rich as part of a separate package, and why not just have it in Django core? And there’s a kind of a philosophy around Django contributions of new features.

Django has a philosophy of being stable and reliable.

Often when somebody will come along with a new feature, the recommendation will be to add that as a third party package that people can install themselves and allow faster development cycle than Django itself. So Django has an eight monthly relay cycle, so it might be quite slow for Django to include new features and correct any changes in an immature package or feature.

And sometimes that’s good enough. It’s there. People can install it if they need it, and then sometimes that can be the basis and the proof point for further consideration of including it in Quora and later date. I think, Adam, you’ve had a number of packages where you’ve had that approach.

Maybe not a number, definitely like a couple, but yeah, I like this idea of cop being proven in the wild before it gets merged and committed for maintenance.

In the earlier days of January, I guess there were features that needed drastic changes after they’ve been added, or they need like a painful deplocation cycle where the old way and the new way both have to work for quite a while before we consider it. So it is nice to see things outside.

For example, here’s the Django rich package. We’ve added a test runner, and now anyone using even Django 2.2, which is still within support for another 15 days, or however it is until the day in April it’s support gets dropped.

People using that such old versions can use it.

Whereas if we made it into January 4.1, the next version at the end of this year, we’d be sitting here not knowing if it worked for like seven more months, and then we finally find out.

That’s kind of a cool benefit of developing stuff as a package first, because then, like you said, people can use it now on even older versions of Django, as long as it supports multiple versions of Jengo.

And if you’re using the longterm support version of January, it might be another year or 18 months before you actually can use that new feature.

Yeah, that’s pretty neat. I didn’t think about it like that since I developed a couple of sites with Django, but not really extensively.

Is it set up such that there’s enough hooks in place that having a Django extension package is relatively easy, or at least doable.

I think one of the things whilst working on this was actually it was very simple to use the test runner, you just need to add an additional setting to your settings, Python to enable this to work and reflected that over the last few weeks. Actually, that’s part of Django’s philosophy and how it’s built. Does it allow these customizations?


Adam, you’ve been working for working with Django for a long time.

Have you felt this way also that extending it’s pretty easy?

Yeah. In general, like everything is replaceable and you can see what you need to replace as well from typical project settings file, because you normally can configure Django by naming the classes that are going to be used, or by apps importing and referencing them.

So if you were looking at say, a Django template engine, you know where that lives inside Django from using it, because you always write out the full import part to that class. So it’s pretty transparent as to how you could jump in and like, oh, if I took that class that for my project, I can make a custom template engine that does so and so a custom database back end or a custom Tesla.


One other thing about I guess why it’s not in Django core itself is the dependency that comes with rich.

Typically I think Django doesn’t take dependent on lightly.

So if we were to include this, you’d be adding dependency on rich and that would be quite a big decision, I would feel for Django itself.

Yeah, it would be for many of the things that Django can use as dependencies, they are completely optional and it’s like Jenko does it try import and if that thing isn’t there, it just doesn’t use it.

But maybe for the test run the best experience would be to explicitly opt in or something.

Maybe it’s better as a package, at least for now, until we see like Richard’s probably pretty stable because even Pip is using it now.

It would be another like.

Okay, that being said, Pip also vendored it.

So yeah, we can’t really vendor things inside a web framework. It would be very responsible to duplicate all the dependencies.

Is it something where you could have it turned on during development and turn it off for deployment?

That’s absolutely viable way for the test run, by definition, is your other commands the way the Django rich thing is, it works. You would be explicitly using the Rich features so you can easily turn them off unless you have two versions of your code.

Would there be a reason to turn it off though? I mean, does it slow it down at all?

I don’t think so. I think Rich is pretty performant. And I set up the Rich runner on a client project last week and used it on CI and GitHub Actions. There’s no colors and it gracefully degrades, so it still renders. Like it’s pretty boxes and layout, but we just don’t get the colors and that’s fine.

Yeah. Okay, cool.

So any future developments for this?

Yes. One future thing that we have got a pull request for is to add timing of outputs as well. So it will output the ten say slowest tests of your test suite and that will then allow you to work out where your slow tests are and look to address those.

Yeah, that would be super useful. There have been packages in the past adding this to Jenkins, test the runner and fallen out of maintenance or not work completely separately. So looking forward to seeing that. And then that’s another thing that’s like built into PYT. So we need a tool for those projects.

Is that a feature that’s out of the box with pytest?

I think it was a plug in that got merged.

So most of the way we’re talking about merging things into Django.

Yeah. So it’s like durations.

And the way pytest works these days internally is a small bundle of plugins, many of these extra features.

One of the things pytest does is support Unit Test classes. So you can move to using pytest, but you don’t have to change all your old tests.

You might want to in the future because you can make use of fixtures and everything, but at least initially you can just start using it on the new tests.

That Unit Test support is built as a plugin that just comes automatically.

So from their Pytra developers survey, they asked developers what Unit testing frameworks they’re using.

So 37% of people say they’re not doing any Unit testing.

Okay, 49% say they use Pi Test and 28% say they use Unit Test. So PY Test is definitely ahead, but not by huge amount.

If we divide those out by what percentage of developers who say they do testing use, which then 44% using Unit Test, 78% use by test. So clearly significant overlap of people using.

Do we know the percentage of just Django users?

No, these stats are for all Python.

Developers okay both are great. And as much as a cheerleader for PY test as I am it would be sad if unit test went away so I’m glad that the Django unit test is getting some love and I want people to keep maintaining the unit test framework in Python itself because it’s a great framework.

Well thank you both for coming on the show and good luck with the timing. I can’t wait to see that and keep us up to date if there’s new cool developments in the Django or Django testing world so thanks a lot.

Thanks for having us. Bye.

Thank you very much.

Thank you Adam and David, great talk. Thanks for your efforts on Django. Thank you Patreon supporters you rock for sticking with me. Seriously, you keep me going keep me going by joining at support and thank you listeners. If you found value in the episode do me a favor, share it, let one of your colleagues know about it. Tweeted audit tell a friend help the podcast grow by one. Thanks for listening. Now go out and try to have fun. Coding.