How to write functional/integration tests in Selenium Python - python

I'm new to testing and I would like to
1) test the login
2) create a folder
3) add content (a page) into the folder
I have each of the tests written and they work but obviously I would like to build ontop of each other, eg, in order to do 3 I need to do 1 then 2. In order to do 2 I need to do 1. This is my basic test structure:
class TestSelenium(unittest.TestCase):
def setUp(self):
# Create a new instance of the Firefox driver
self.driver = webdriver.Firefox()
def testLogin(self):
print '1'
...
def testFolderCreation(self):
print '2'
...
def testContentCreation(self):
print '3'
...
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
At first, I thought the tests would run in order and the 2nd function would continue off where the first one left off, but I've found this is not the case, it seems to be starting over with each test. I've also realized that they execute in reverse order. I get an output of 3,2,1 in the terminal. How should I achieve what I want? If I call the previous functions before I run the one I want, I feel like it's repetitively testing the same thing over and over since each one is a test (eg, in testContentCreation, I would call 'testLogin' then call testFolderCreation and inside testFolderCreation call testLogin. If I were to do more, the testLogin would've been called a number of times!). Should I instead turn the previous steps into regular non-test functions and in the final last one (the test function) call the previous ones in order? If I do it that way then I guess if any of the steps fail, the last one fails, there would be one big test function.
Any suggestions on how you should write this type of test?
Also, why are the tests running in reverse order?
Thanks!

You are seeing what you are seeing, I think, because you are making some incorrect assumptions about the assumptions unittest makes. Each test case is assumed to be a self-contained entity, so there is no run order imposed. In addition, SetUp() and TearDown() operate before and after each individual case. If you want global setup/teardown, you need to make classmethods named SetUpClass() and TearDownClass(). You may also want to look in to the TestSuite class. More here: http://docs.python.org/library/unittest.html
Keep in mind that when the unittest library does test discovery (reflects your testcase class to find the test cases to run), it is essentially limited to looking at the .__dict__ and dir() values for the object, which are inherently unordered.

Related

Pytest class scope parametrization

I have a couple of fixtures that do some initialization that is rather expensive. Some of those fixtures can take parameters, altering their behaviour slightly.
Because these are so expensive, I wanted to do initialisation of them once per test class. However, it does not destroy and reinit the fixtures on the next permutation of parameters.
See this example: https://gist.github.com/vhdirk/3d7bd632c8433eaaa481555a149168c2
I would expect that StuffStub would be a different instance when DBStub is recreated for parameters 'foo' and 'bar'.
Did I misunderstand something? Is this a bug?
I've recently encountered the same problem and wanted to share another solution. In my case the graph of fixtures that required regenerating for each parameter set was very deep and it's not so easy to control. An alternative is to bypass the pytest parametrization system and programmatically generate the test classes like so:
import pytest
import random
def make_test_class(name):
class TestFoo:
#pytest.fixture(scope="class")
def random_int(self):
return random.randint(1, 100)
def test_someting(self, random_int):
assert random_int and name == "foo"
return TestFoo
TestFooGood = make_test_class("foo")
TestFooBad = make_test_class("bar")
TestFooBad2 = make_test_class("wibble")
You can see from this that three tests are run, one passes (where "foo" == "foo") the other two fail, but you can see that the class scope fixtures have been recreated.
This is not a bug. There is no relation between the fixtures so one of them is not going to get called again just because the other one was due to having multiple params.
In your case db is called twice because db_factory that it uses has 2 params. The stuff fixture on the other hand is called only once because stuff_factory has only one item in params.
You should get what you expect if stuff would include db_factory as well without actually using its output (db_factory would not be called more than twice):
#pytest.fixture(scope="class")
def stuff(stuff_factory, db_factory):
return stuff_factory()

Python unit test is not running

I am trying to define a test method. Currently I am not receiving any errors, but the test is not actually running. The test is trying to make sure that only the first word in a string that is in list_first_words is being returned.
import unittest
class TestSong(unittest.TestCase):
def first_words_list(self):
self.assertEqual(Song().firstwords(["hello world"]),["hello"])
if __name__ == "__main__":
unittest.main()
Code that is being tested:
def firstwords(self,large_song_list):
all_first_words = [] # Create an empty list
for track in large_song_list:
first_word = track.trackName.partition(' ')[0]
all_first_words.append(first_word)
return all_first_words
You need to rename the test method to test_first_words_list.
Tests are discovered by unittest only when they start with the word test. See "Organizing Test Code" in the documentation for more details.
As described in the documentation:
A testcase is created by subclassing unittest.TestCase. The three individual tests are defined with methods whose names start with the letters test. This naming convention informs the test runner about which methods represent tests.
So, you need to rename the method starts with test.

How do I find out if the current test is the last to be run?

How can I find out from the current test if its the last to be run? (Python unittest / nosetests)
I have some specific fixture teardown to be done at the very end of the test run and it would be a lot easier if on a test by test basis I could just determine:
if last_test:
hard_fixture_teardown()
else:
soft_fixture_teardown()
I have a package teardown which would work perfectly but it seems very messy passing the fixture information back to the __init__.teardown_package().
You can use a combination of TestCase.tearDown() and TestCase.tearDownClass() to achieve this. tearDown() is called for each test method while tearDownClass() is called after all tests in the class have run.
As stated here unit test are not meant to have an order, unit tests depending on the order are either not well conceived or just have to be merged in a monolithic one. (merging separate functions in a single test is the accepted answer )
[edit after comment]
If the order is not important you can do this (quite messy, imo we are still forcing the boundaries of how unit tests should be used)
in every test package you put:
def tearDownModule():
xxx = int(os.getenv('XXX', '0')) + 1
if xxx == NUMBER_OF_TEST_PACKAGES:
print "hard tear down"
else:
print "not yet"
os.environ['XXX'] = str(xxx)
with NUMBER_OF_TEST_PACKAGES imported from somewhere global.
also if the order is not important I suppose that when used the fixture is only readed and not modified, if so you can setup that as a class method
#classmethod
def setUpClass(cls):
print "I'll take a lot of time here"

Python: Modify SetUp based on TestCase in unittest.TestCase

I want each testCase while loading setup function should declare different values of "x". Is there a way I can achieve in setUp function. Sample code is mentioned below. How to change PSEUDO CODE in setUp function below?
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
# ***PSEUDO CODE***
x = 10 # if test_shuffle uses setUp()
x = 20 # if test_choice uses setUp()
x = 30 # if test_sample uses setUp()
# ***PSEUDO CODE***
def test_shuffle(self):
#test_shuffle
def test_choice(self):
#test_choice
def test_sample(self):
#test_choice
if __name__ == '__main__':
unittest.main()
I can achieve by writing each testcase in different file but I would drastically increases number of files.
One unittest file thematically captures tests that all cover similar features. The setup is used to get that feature into a testable state.
Move that assignment of X into the actual test method (keeps X = 0 in the setup if you want every test to actually have an X). It makes it clearer when reading the test exactly what is happening and how it is being tested. You shouldn't have conditional logic that affect how tests work inside your setup function because you are introducing complexity into the test's preconditions, which means you have a much larger surface area for errors.
Perhaps I am missing the point, but the assignment in your pseudo code could just be moved to the start of the corresponding test. If the "assignment" is more complex, or spans multiple tests, then just create functions outside the test case but inside the file and the corresponding tests invoke whatever functions are supposed to be part of their "setUp".

calling self test case does not increment the number of tests passed?

Suppose I have a unittest like this
class TestABC(unittest.TestCase):
def setUp(self):
....
def test001_abc(self):
....
def test002_abc(self):
....
def test003_bac(self):
....
self.test001_abc()
But the output shows Run 3 tests in 10.962s. I believe that the last self.test001_bac() had been ran, but can we indicate this in the test count?
Thanks.
The last "test" was run as part of test_003_bac, so unittest does not see it as a separate test. I'm not sure what you're trying to achieve with this, but running one test inside another is not a good idea. nose supports the concept of Test Generators, which might do what you want.
Your question doesn't make sense. There are just three tests in your code; the fact that the last test calls another test doesn't magically "split" the test case into two, independent tests - test003_bac is still just one, single test.

Categories