Following the test driven development with python book I got stuck
I have tried several different imports but still nothing.. anyone?
Error
$python manage.py test functional_tests
ERROR: test_can_start_a_list_and_retrieve_it_later (functional_tests.tests.NewVisitorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/coelhao/DjangoProjects/superlists/functional_tests/tests.py", line 45, in
test_can_start_a_list_and_retrieve_it_later
self.assertRegex(edith_list_url, '/lists/.+') AttributeError: 'NewVisitorTest' object has no attribute 'assertRegex'
Code
from django.test import LiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unittest
class NewVisitorTest(LiveServerTestCase):
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self):
self.browser.quit()
def test_can_start_a_list_and_retrieve_it_later(self):
# .....
# When she hits enter, the page updates, and now the page lists
# "1: Buy peacock feathers" as an item in a to-do list table
inputbox.send_keys(Keys.ENTER)
edith_list_url = self.browser.current_url
self.assertRegex(edith_list_url, '/lists/.+')
self.check_for_row_in_list_table('1: Buy peacock feathers')
# ....
I'm assuming you are on Python 2 - then use assertRegexpMatches instead of assertRegex.
assertRegex was introduced in Python 3:
Changed in version 3.2: The method assertRegexpMatches() has been
renamed to assertRegex().
There is no such assertion as assertRegex - perhaps you mean assertRegexMatches?
The unittest docs are here: http://docs.python.org/2.7/library/unittest.html#unittest.TestCase
Related
I am using HtmlTestRunner to generate my test report, but I am not able to understand why I am getting this error: "TypeError: issubclass() arg 1 must be a class"
My setup is Python 3.6, pytest, Ubuntu 17.10.
This is the code I have written:
from pages.Home.category_page import CategoryPage
from utilites.testStatus import TestStatus
import pytest
import unittest
import time
#pytest.mark.usefixture("oneTimeSetUp","setUp")
class CategoryTest(unittest.TestCase):
#pytest.fixture(autouse=True)
def classSetup(self,oneTimeSetUp):
self.ca = CategoryPage(self.driver)
self.ts = TestStatus(self.driver)
#pytest.mark.run(order=1)
def test_Announcements_link_WAF001(self):
result = self.ca.find_announcements_link()
self.ts.markFinal("Announcements link", result,"To find announcements link")
time.sleep(2)
#pytest.mark.run(order=2)
def test_FirstLinkInAnnouncements_WAF002(self):
result=self.ca.find_first_announcement_link()
self.ts.markFinal("Latest link in announcements",result,"To click on latest announcements link")
time.sleep(2)
#pytest.mark.run(order=3)
def test_Products_Link_WAF003(self):
result=self.ca.find_products()
self.ts.markFinal("Products link",result,"To find products link")
time.sleep(2)
#pytest.mark.run(order=4)
def test_FirstLinkInProducts_WAF004(self):
result=self.ca.find_first_products_link()
self.ts.markFinal("Latest link in products",result,"To click on latest products link")
time.sleep(2)
The test suite runner:
from unittest import TestLoader, TestSuite
from HtmlTestRunner import HTMLTestRunner
from tests.Home import category_test
example_tests = TestLoader().loadTestsFromTestCase(category_test)
suite = TestSuite(example_tests)
runner = HTMLTestRunner(output='example_suite', template='path/to/template', report_title='My Report')
runner.run(suite)
This is the resulting error:
Traceback (most recent call last):
File "/home/manoj/PycharmProjects/untitled8/test/test_suite.py", line 6, in <module>
example_tests = TestLoader().loadTestsFromTestCase(to_test_login)
File "/usr/lib/python3.6/unittest/loader.py", line 85, in loadTestsFromTestCase
if issubclass(testCaseClass, suite.TestSuite):
TypeError: issubclass() arg 1 must be a class
Your problem is that you are passing the test module, instead of the test class, to the runner. If you look at unittest's documentation for loadTestsFromTestCase, you'll see its argument needs to be a TestCase-derived class.
I reduced your example to a minimal version to simplify my answer a bit:
In tests.py:
import unittest
class MyTestCase(unittest.TestCase):
def test_something(self):
assert True
runner.py, based on yours:
from unittest import TestLoader, TestSuite, TextTestRunner
import tests
example_tests = TestLoader().loadTestsFromTestCase(tests)
suite = TestSuite(example_tests)
runner = TextTestRunner()
runner.run(suite)
This will give the following output:
$ python runner.py
Traceback (most recent call last):
File "runner.py", line 4, in <module>
example_tests = TestLoader().loadTestsFromTestCase(tests)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 85, in loadTestsFromTestCase
if issubclass(testCaseClass, suite.TestSuite):
TypeError: issubclass() arg 1 must be a class
If I switch runner.py to use the class instead, it works:
from unittest import TestLoader, TestSuite, TextTestRunner
from tests import MyTestCase
example_tests = TestLoader().loadTestsFromTestCase(MyTestCase)
suite = TestSuite(example_tests)
runner = TextTestRunner()
runner.run(suite)
Output:
$ python runner.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
You should be able to adapt this to your code. That being said, the pytest integration might not work with HtmlTestRunner, which is unittest-based. Make sure you look into pytest-html
I have a little issue with webdriver.My machine run windows 7 and successfuly install python and selenium webdriver.Here is the problem
When i run this file
from selenium import webdriver
import HTMLTestRunner
import unittest
class nexmo(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://wwww.facebook.com")
def test_login(self):
emailFieldId = "email"
el = self.driver.find_element_by_id(emailFieldId)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
The test give me
Ran 0
OK But the Firefox doesnt start and do the things i tell him.
When I run
from selenium import webdriver
self.driver = webdriver.Firefox()
self.driver.get("http://wwww.facebook.com")
emailFieldId = "email"
el = self.driver.find_element_by_id(emailFieldId)
self.driver.quit()
Everything is OK.The browser starts and find the element.
I took your code and copy/pasted it into my Eclipse and it ran fine.
By chance did you re-type this code into SO rather than copy paste? Is it possible that there is a typo in your "def test_login(self):" line such that unittest can't identify it as a test case? This is my best guess. Since unittest first checks to see if you have any unit tests (identified as a function with the pre-fix "test_". If and only if it finds a test case will it run setUp and tearDown.
Also, the point of unit testing is to actually test that you received a valid value. Can I recommend adding this to the end of "def test_login":
self.assertIsNotNone(el)
I am following the book TDD with Python. In chapter 1 there is a piece of code
from selenium import webdriver
import unittest
class NewVisitorTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(5)
def tearDown(self):
self.browser.quit()
def test_can_start_a_list_and_retrieve_it_later(self):
self.browser.get('http://localhost:8000')
self.assertIn('To-Do', self.browser.title)
self.fail('Finish the test!')
if __name__ == '__main__':
unittest.main(warnings='ignore')
The file is called functional_tests.py. I have django 1.7 and selenium installed globally on Ubuntu 14.04. I also started fresh project superlists. I run the server before I try the tests. When I run the test with
python3 functional_tests.py
Firefox window opens up and loads the default Django startup page and the window stays open even though it should close after the test runs. Also there is no output from the tests at all. I was expecting something like this:
F
======================================================================
FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest)
---------------------------------------------------------------------
Traceback (most recent call last):
File "functional_tests.py", line 18, in
test_can_start_a_list_and_retrieve_it_later
self.assertIn('To-Do', self.browser.title)
AssertionError: 'To-Do' not found in 'Welcome to Django'
---------------------------------------------------------------------
Ran 1 test in 1.747s
FAILED (failures=1)
What could be the problem? Thanks
Have you installed recent version of Selenium? As mentioned in the book, you should have matching version of Firefox and Selenium.
I am trying to add some selenium tests to my Django project, but the second test always fails with a Server Error (500) . Since both tests start exactly the same, I figure it must have something to do with the setUp and tearDown methods. Can someone help? Thanks.
from django.test import LiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.contrib.auth.models import User
from selenium.webdriver.support.ui import Select
class UserTest(LiveServerTestCase):
def setUp(self):
User.objects.create_user(username='user', password='pass', email='test#test.com')
self.browser = webdriver.Chrome()
def tearDown(self):
self.browser.quit()
def changeSelector(self, browser, value):
mealSelector = Select(browser.find_element_by_id('mealsToday'))
mealSelector.select_by_visible_text(str(value))
def login_user(self):
self.browser.get(self.live_server_url)
self.timeout(5)
self.assertIn('Animals', self.browser.title)
# Log in
login_button = self.browser.find_element_by_id('login').click()
self.browser.find_element_by_id('id_username').send_keys('user')
self.browser.find_element_by_id('id_password').send_keys('pass')
def timeout(self, time_to_sleep):
import time
time.sleep(time_to_sleep)
def test_one_test(self):
self.login_user()
def test_two_test(self):
self.login_user()
Edit: I should mention that the first test works fine and returns success. Any test after the first one fails right on starting up with the 500 error.
Edit 2: What I see when I run my tests:
======================================================================
FAIL: test_two_test (functional_tests.tests.UserTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/functional_tests/tests.py", line 34, in test_two_test
self.login_user()
File "/functional_tests/tests.py", line 20, in login_user
self.assertIn('Animals', self.browser.title)
AssertionError: 'Animals' not found in 'http://localhost:8081/'
Even this minimal code fails:
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.contrib.auth.models import User
from selenium.webdriver.support.ui import Select
class UserTest(StaticLiveServerTestCase):
def setUp(self):
self.browser = webdriver.Chrome()
def tearDown(self):
self.browser.quit()
def login_user(self):
self.browser.get(self.live_server_url)
self.assertIn('Animals', self.browser.title)
def test_one_test(self):
self.login_user()
def test_two_test(self):
self.login_user()
The second time the get is called in the second method I can see that the 500 Error is there and that nothing is correctly loaded. Why would this be?
After some code to be able to show me errors (the testing suite sets DEBUG=False to closer simulate the real env) by setting DEBUG=True
Then I saw that the code was bombing because a row wasn't there that the system expected. This is because I add this row in a migration script. This passes the first test because all migration scripts are run at the beginning of testing, but after all data is deleted after the first test, it is never added again.
It's difficult to say without seeing the complete traceback, but, it could be because of the create_user() call - it fails to create a user with an existing username. Try moving the create_user() under the setUpClass():
class UserTest(LiveServerTestCase):
#classmethod
def setUpClass(cls):
User.objects.create_user(username='user', password='pass', email='test#test.com')
super(UserTest, cls).setUpClass()
def setUp(self):
self.browser = webdriver.Chrome()
Maybe, it will be useful for somebody.
I have problems with testing with Selenium using LiveServerTestCase, Debug was True, all about last answers were about was OK.
But, earlier I tried to deploy my web-application on Heroku, and I have such line of code in my settings.py:
django_heroku.settings(locals())
But when I removed it, I didn't catch this error.
I am trying to run a selenium test and this seems nothing happening. I tested the following code to make sure the setting was working: the firefox browser loaded as it is expected.
In functional_tests.py
browser = webdriver.Firefox()
broswer.get('http://localhost:8000')
But when I changed it to as follows:
import unittest
from selenium import webdriver
class NewVistorTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def tearDown(self):
self.browser.quit()
def test_can_open_browser(self):
self.browser.get('http://localhost:8000')
self.assertIn('Test', self.browser.title)
It was not opening the browser, nothing was happening. I ran this python functional_tests.py
What is the best way to organize unit tests and selenium tests. I'd like to run it by module name, not all in tests.py or test_abc.py, not by nose.
How do you expect it to run? Python won't automatically run tests, just because they're in a class. You need to add a couple more lines to the end of your file:
class NewVistorTest(unittest.TestCase):
...
if __name__ == '__main__':
unittest.main(warnings='ignore')
This conditional is how a Python script checks if it has been executed from the command line, rather than just imported by another script. We call unittest.main() to launch the unittest test runner, which will automatically find test and methods in the file and run them.
Without that block, as you've seen, nothing happens.