Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Django Basics Test Time Django TDD

Katelyn Polahar
Katelyn Polahar
2,691 Points

How can I tell which tests are passing and which are not?

Let me start by saying that I have done the rest of these tutorials on my own file system, rather than in the workspace. So it is very possible that the issue here stems from something I need to do differently to run the tests on workspaces instead of my own computer.

The readme file says that I can run the tests in the console using 'python manage.py tests'. Which, I figure I could use to comment out some of the tests, and check each one to see if it passes. First of all, running that returns an unknown command error. So I ran 'python manage.py test' instead, and I keep getting what I think is a database error. But since the code challenge only has me handle the three specific files, I have to assume that I'm not supposed to edit any other files, so I haven't. But I'm not sure what's going on with the database. Assuming that's the problem. Here's the error I get (it's long, but I figure it's better to include the whole thing):

treehouse:~/workspace/karaoke$ python manage.py test
Creating test database for alias 'default'...
Traceback (most recent call last):
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: songs_performer

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/init.py", line 353, in execute_from_command_lin e
utility.execute()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/init.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/commands/test.py", line 30, in run_from_argv
super(Command, self).run_from_argv(argv)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/commands/test.py", line 74, in execute
super(Command, self).execute(*args, **options)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/base.py", line 399, in execute
output = self.handle(*args, **options) File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/management/commands/test.py", line 90, in handle
failures = test_runner.run_tests(test_labels)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/test/runner.py", line 532, in run_tests
old_config = self.setup_databases()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/test/runner.py", line 482, in setup_databases
self.parallel, **kwargs
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/test/runner.py", line 726, in setup_databases
serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/base/creation.py", line 78, in create_test_db
self.connection.test_serialized_contents = self.serialize_db_to_st ring()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/base/creation.py", line 122, in serialize_db_to_string serializers.serialize("json", get_objects(), indent=None, stream=ou t)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/serializers/
init.py", line 129, in serialize
s.serialize(queryset, **options)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/core/serializers/base.py", line 79, in serialize
for count, obj in enumerate(queryset, start=1):
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/base/creation.py", line 118, in get_objects
for obj in queryset.iterator():
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/models/query.py", line 52, in __iter
_
results = compiler.execute_sql()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/models/sql/compiler.py", line 848, in execute_sql
cursor.execute(sql, params)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/utils.py", line 95, in exit
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/dja ngo/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: songs_performer

songs/models.py
from django.db import models

class Performer(models.Model):
  name = models.CharField(max_length=255)

  def __str__(self):
    return self.name

class Song(models.Model):
  title = models.CharField(max_length=255)
  artist = models.CharField(max_length=255)
  performer = models.ForeignKey(Performer)
  duration = models.IntegerField(default=0)

  def __str__(self):
    display = self.title.join(' by ').join(self.artist)
    return display
songs/views.py
from django.shortcuts import get_object_or_404, render
from .models import Performer, Song

def performer_detail(request, pk):
  performer = get_object_or_404(Performer, pk=pk)
  return render(request, 'songs/performer_detail.html', {'performer': performer})

def song_detail(request, song_pk, perf_pk):
  song = get_object_or_404(Song, performer_id=perf_pk, pk=song_pk)
  return render(request, 'songs/song_detail.html', {'song': song})

def song_list(request):
  songs = Song.objects.all()
  return render(request, 'songs/song_list.html', {'songs': songs})
songs/templates/songs/performer_detail.html
{% extends 'base.html' %}

{% block title %}{{ performer.name }}{% endblock %}

{% block content %}
<h2>
  <a href="{% url 'performer:detail', pk=song.performer.pk %}">{{ performer }}</a>
</h2>
{% endblock %}

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,441 Points

One way to run the tests with more details is to use the -v verbose switch:

python manage.py test -v 2

This will produce output similar to: (your migrations may be different)

$ python manage.py test -v 2
Creating test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: contenttypes, songs, sessions, admin, auth
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying sessions.0001_initial... OK
  Applying songs.0001_initial... OK
  Applying songs.0002_auto_20150912_1204... OK
  Applying songs.0003_auto_20150912_1210... OK
  Applying songs.0004_song_performer... OK
  Applying songs.0005_song_length... OK
  Applying songs.0006_auto_20150912_1241... OK
  Applying songs.0007_remove_performer_song... OK
  Applying songs.0008_song_performer... OK
test_performer_string (songs.tests.PerformerModelTests)
String version of Performer should be Performer's name attribute ... ok
test_song_string (songs.tests.SongModelTests)
String version of Song should contain the title and artist ... ok
test_performer_detail_view (songs.tests.ViewTests)
The performer_detail view should: ... ok
test_song_detail_view (songs.tests.ViewTests)
The song_detail view should: ... ok
test_song_list_view (songs.tests.ViewTests)
The song_list view should: ... ok

----------------------------------------------------------------------
Ran 5 tests in 0.183s

OK
Destroying test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...

Quickly scanning your code, I see two areas to work on.

  • The performer_detail template references song.performer.pk, but "song" is not passed in the context provided by the view performer_detail.

  • the song.__str__ method needs work. The display statement is not correct:

display = self.title.join(' by ').join(self.artist)

If run with a title of "this is a thing" by artist "BOBBY JONES", the method output would be:

'B this is a thingbthis is a thingythis is a thing O this is a thingbthis is a thingythis is a thing B this is a thingbthis is a thingythis is a thing B this is a thingbthis is a thingythis is a thing Y this is a thingbthis is a thingythis is a thing this is a thingbthis is a thingythis is a thing J this is a thingbthis is a thingythis is a thing O this is a thingbthis is a thingythis is a thing N this is a thingbthis is a thingythis is a thing E this is a thingbthis is a thingythis is a thing S'

Instead of using join, try using a simple "{} by {}".format(title, artist) structure.

Katelyn Polahar
Katelyn Polahar
2,691 Points

Thank you for taking the time to look at this! I'm in the middle of something else this week, but I'll try making the changes you suggested when I get a sec!