2

I learned Django functional test from the TDD with Python and adjust to my project.

My FT is really simple, check the title of url.

I use live_server_url to test by selenium. But it goes to another port number(56458), not 8000. (When I follow the book, it wasn't)

$ python manage.py runserver &
...
Starting development server at http://127.0.0.1:8000/
...
$ python manage.py test functional_test
...
http://localhost:56458
E
======================================================================
...

My functional_tests/tests.py is :

from django.test import LiveServerTestCase

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import WebDriverException

from time import time, sleep


class NewVistorTest(LiveServerTestCase):

    def setUp(self):
        self.browser = webdriver.Firefox()
        self.browser.implicitly_wait(3)


    def tearDown(self):
        self.browser.quit()

    def test_render_a_list_of_candiates_in_home(self):
        self.browser.get(self.live_server_url)
        h1_text = self.browser.find_element_by_tag_name('h1').text

        self.assertEqual(self.browser.title, 'Voting Dapp')
        self.assertEqual(h1_text, 'A Simple Voting Application')

Doc says:

The live server listens on localhost and binds to port 0 which uses a free port assigned by the operating system. The server’s URL can be accessed with self.live_server_url during the tests.

So I try to look listening ports(I think I'm immature for this part):

$ netstat | grep LISTEN
$ # nothing printed!
홍한석
  • 439
  • 7
  • 21
  • 1
    Can you add the contents of functional_test/tests.py? I bet your test is spinning up it's own server. That is okay because you always want to test a clean and empty project. You do not want to test a site polluted with development data. Also, why test the domain and port? With most projects this is configured in the webserver and not in the Django project. I think therefor the domain name and port are out of scope. You should be fine testing absolute paths only. – allcaps Dec 31 '17 at 11:30
  • @allcaps Thanks! Added the unctional_test/tests.py. I practice like the TDD book. – 홍한석 Jan 01 '18 at 08:56

4 Answers4

2

You use a LiveServerTestCase. It launches a Django server for you. No need to start a server like you did in the previous chapter.

LiveServerTestCase does basically the same as TransactionTestCase with one extra feature: it launches a live Django server in the background on setup, and shuts it down on teardown. This allows the use of automated test clients other than the Django dummy client such as, for example, the Selenium client, to execute a series of functional tests inside a browser and simulate a real user’s actions.

https://docs.djangoproject.com/en/2.0/topics/testing/tools/#django.test.LiveServerTestCase

So it is expected that your test server has some other port than the development server. Also the test server is an empty project with an empty db. So your test needs to create the needed content before you execute the actual test case.

Alternatively you can point to tests to some other environment with --liveserver LIVESERVER. See python manage.py test -h.

I think it is wrong to test against the development server as this data can be altered (manually and by previous tests) and therefore is not reproducible. I believe tests should be entirely self contained, such that it can be run either in isolation or in arbitrary combination with any number of other test cases.

allcaps
  • 10,945
  • 1
  • 33
  • 54
2
from selenium import webdriver
from django.urls import reverse
import time

class TestApiPages(StaticLiveServerTestCase):
  
  def setUp(self):
      self.browser = webdriver.Chrome('functional_test/chromedriver.exe')
  
  def tearDown(self):
      self.browser.close()
  
  def test_api_list_displayed(self):
      self.browser.get(('%s%s' % (self.live_server_url, '/admin/')))
     
1

I got stuck same problem like you. Same exeception. So what actually problem is my home page url. Where my home page url is like : http://127.0.0.1:8000/api/ but server is trying with http://localhost:56458/.

self.browser.get(('%s%s' % (self.live_server_url, '/api/')))
0

I am also reading the TDD Python book. I am using Django 2.1, instead of Django 1.11. I faced the same problem as you described. I found out in setUpClass(), have to call super().setUpClass().

@classmethod
def setUpClass(cls):
    super().setUpClass()

Similar in tearDownClass().

Ken Cloud
  • 853
  • 7
  • 6