google test fixture one time action - googletest

I've started to use google test fixture and
in my test suite I need to open/close a file only once , open the file before the first test start and close it after that the last test has been executed.
I wonder if there is a method of the fixture that
allow to do an action only ones at the beginning/end of the test suite.

Declare static member variable to hold file object and define it outside the fixture class.
After that, define static void SetUpTestSuite() and use it to open your file and static void TearDownTestSuite() to close your file.
google test will call SetUpTestSuite() before first test and TearDownTestSuite() after last test.
You can also check Sharing Resources Between Tests in the Same Test Suite from the official documentation

Related

How to restrict test data method call for respective Test method by using TestCaseSource attribute in NUnit

I am using NUnit for the Selenium C# project. In which I have many test methods. For getting data (from excel) I am using a public static method that returns IEnumerable<TestCaseData> which I am calling at test method level as TestCaseSource. I am facing challenges now, as I start executing on the test method it is invoking all the static methods which are there in the project.
Code looks like this:
public static IEnumerable<TestCaseData> BasicSearch()
{
BaseEntity.TestDataPath = PMTestConstants.PMTestDataFolder + ConfigurationManager.AppSettings.Get("Environment").ToString() + PMTestConstants.PMTestDataBook;
return ExcelTestDataHelper.ReadFromExcel(BaseEntity.TestDataPath, ExcelQueryCreator.GetCommand(PMTestConstants.QueryCommand, PMTestConstants.PMPolicySheet, "999580"));
}
[Test, TestCaseSource("BasicSearch"), Category("Smoke")]
public void SampleCase(Dictionary<string, string> data)
{
dosomething;
}
Can someone help me how can I restrict my data call method to the respective test method?
Your TestCaseSource is not actually called by the test method when you run it, but as part of test discovery. While it's possible to select a single test to execute, it's not possible to discover tests selectively. NUnit must examine the assembly and find all the tests before it's possible to run any of them.
To make matters worse, if you are running under Visual Studio, the discovery process takes place multiple times, first before the tests are initially displayed and then again each time the tests are run. This is made necessary by the architecture of the VS Test Window, which runs separate processes for the initial disovery and the execution of the tests.
That makes it particularly important to minimize the amount of work done in test discovery, especially when running under Visual Studio. Ideally, you should structure the code so that the variable parameters are recorded during discovery. The actual data access should take place at execution time. This can be done in a OneTimeSetUp method, a SetUp method or at the start of the test itself.
Finally, I'd say that your instinct is correct: it should be possible to set up a TestCaseSource, which only runs if the test you select is about to be executed. Unfortunately, that's a feature that NUnit doesn't yet have.

In NUnit [TearDown], how to find out whether the test was run solo?

So, in TearDown, I have got the info about the test outcome and the test result message, but I would like to handle things specifically on whether the test was run solo (a single test in the test session) or was started in a whole set of tests (e.g. "Run all tests/All tests from Solution").
The goal is to detect, whether the developer individually started the test (manually, from within Visual Studio) or it was started using a Continuous Integration system.
This is what I have so far:
/// <summary>
/// A helper function for resolving problems when string comparison fails.
/// </summary>
/// <remarks>
/// Intended to be used to analyze the detected differences.
/// </remarks>
[TearDown]
public void CompareNonMatchingStringsOnFailure() {
if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed) {
string outputMessage = TestContext.CurrentContext.Result.Message;
if (outputMessage.StartsWith("Expected string to be ")) {
// do extended comparison
// This should only run on single runs, which were initiated manually from visual studio
//...
}
}
}
How to get info about the test run/session in the TearDown method?
You can't do this in the code of a teardown because (1) TearDown is still part of a test and (2) tests are not supposed to know anything about who ran them, why they are running etc. The execution environment knows about the test, but the test does not know the execution environment. In fact, NUnit goes to a lot of trouble to make sure things work the same in each environment. While there are ways to trick NUnit, they are generally bad ideas and version-dependent.
Here's what you can do...
Create a fixture that inherits from your fixture.
Put the logic you want in the new fixture TearDown method.
Mark the new fixture as [Explicit].
Do not add any categories to the new fixture.
Because of (3) the new fixture will not run as part of CI or even from the IDE when you run all tests.
It can only be run explicitly. Since it has no categories, that means it can only be run by name... i.e. by selecting the entire fixture or a single test.
That isn't quite what you asked for. If you run the entire fixture, you will get the full comparison for all the inherited test methods. However, it may be sufficient for what you are trying to accomplish.

GO Unit testing structured REST API projects

I am trying to write nice unit tests for my already created REST API. I have this simple structure:
ROOT/
config/
handlers/
lib/
models/
router/
main.go
config contains configuration in JSON and one simple config.go that reads and parses JSON file and fills the Config struct. handlers contains controllers (i.e. handlers of respective METHOD+URL described in router/routes.go). lib contains some DB, request responder and logger logic. models contains structs and their funcs to be mapped from-to JSON and DB. Finally router contains the router and routes definition.
Now I was searching and reading a lot about unit testing REST APIs in GO and found more or less satisfying articles about how to set up a testing server, define routes and test my requests. All fine. BUT only if you want to test a single file!
My problem is now how to set up the testing environment (server, routes, DB connection) for all handlers? With the approach found here (which I find very easy to understand and implement) I have one problem: either I have to run tests separately for each handler or I have to write test suites for all handlers in just one test file. I believe you understand that both cases are not very happy (1st because I need to preserve that running go test runs all tests that succeed and 2nd because having one test file to cover all handler funcs would become unmaintainable).
By now I have succeeded (according to the linked article) only if I put all testing and initializing code into just one func per XYZhandler_test.go file but I don't like this approach as well.
What I would like to achieve is kind of setUp() or init() that runs once with first triggered test making all required variables globally visible and initialized so that all next tests could use them already without the need of instantiating them again while making sure that this setup file is compiled only for tests...
I am not sure if this is completely clear or if some code example is required for this kind of question (other than what is already linked in the article but I will add anything that you think is required, just tell me!
Test packages, not files!
Since you're testing handlers/endpoints it would make sense to put all your _test files in either the handlers or the router package. (e.g. one file per endpoint/handler).
Also, don't use init() to setup your tests. The testing package specifies a function with the following signature:
func TestMain(m *testing.M)
The generated test will call TestMain(m) instead of running the tests
directly. TestMain runs in the main goroutine and can do whatever
setup and teardown is necessary around a call to m.Run. It should then
call os.Exit with the result of m.Run
Inside the TestMain function you can do whatever setup you need in order to run your tests. If you have global variables, this is the place to declare and initialize them. You only need to do this once per package, so it makes sense to put the TestMain code in a seperate _test file. For example:
package router
import (
"testing"
"net/http/httptest"
)
var (
testServer *httptest.Server
)
func TestMain(m *testing.M) {
// setup the test server
router := ConfigureRouter()
testServer = httptest.NewServer(router)
// run tests
os.Exit(m.Run())
}
Finally run the tests with go test my/package/router.
Perhaps you could put the setup code that you want to use from multiple unit test files into a separate package that only the unit tests use?
Or you could put the setup code into the normal package and just use it from the unit tests.
It's been asked before but the Go authors have chosen not to implicitly supply a test tag that could be used to selectively enable function compiles within the normal package files.

Selenium, questions about code re-factoring

With Selenium IDE I generate a sample script for test the log to a website and a value in the website after logging. So my script is (Java) :
#test
public void mytest() throws Exception{
// Load the home page
...
// complete the log form
...
// check if the log work
...
// Logged : click on some element in the page
...
// Logged ; check the information X (if one HTML element contains child or not
...
}
I use JUnit for run the test class from a main class. My question is : What is the best way for re-factoring my code ? I would like create one class by "step", is it possible ? by example :
Class for load page and check there isn't error 404
Class for complete the log form, submit and check if the user is logged
Class for navigate in the website and get the information I want
Is it the best way? There isn't a real goal. Just, I want know how organize the code for a maximum of reuse (sorry for my bad English x) )
There are couple of reasons why you do not want to use Selenium IDE, do the recording for the test cases and refactor the code afterwards. Most of the time selenium IDE will provide you the selectors that are not stable enough. For rerunning the tests you want to make sure the selectors are stable enough and will not possibly depend on html structure. Second, as the test suite getting larger you want to reduce the code duplication as much as possible. Using Selenium IDE there is no way to understand which code blocks can be reused.
So, bottom line is for a good test suite start building a framework from scratch instead of using Selenium IDE. There are a lot of example out there how to start. I have one with TestNG here if that helps.

How to get Selenium and TestNG to open one browser to run tests in multiple classes

I am using Selenium with TestNG to test a website. I have created tests using the Selenium IDE and exported them to TestNG with each test being a method in a class. Eg,
For login tests there is a Login class which has methods testLogin(), testLogin2() etc
For signup tests there is a Signup class has methods testSignup(), testSignup2(), etc
I am using Ant to run the tests which works fine except that each class will open up a browser and then run its methods, eg, if I have five classes, then five browsers will open simultaneously and then run the tests.
What I want is to get Ant/Selenium/TestNG to just open up one browser and then run all the tests (in the same browser) in all the classes that I have specified in testng.xml. Using the example above, I want one browser to open then run testLogin(), testLogin2(), testSignup(), testSignup2().
If this cannot be achieved, then I want to open a browser, run all tests in a class then close the browser then open another browser then run the set of test methods in the next class.
Any help appreciated. Thanks in advance.
Today I have found the answer that works for me. Give me a few minutes to gather all code samples :)
Init.java
//base class that will be called before all tests
#Test(groups = "init")
public class Init{
DefaultSelenium browser;
public void start(ITestContext itc){
browser = (DefaultSelenium) itc.getAttribute("browser");
browser.open("url");
browser.click("xpath");
}
}
TemplateForClasses.java
/* - all public methods will be tests
* - all tests will be called after group init
* - just before suite will start we will start 1 browser instance
*/
#Test(dependsOnGroup="init")
public class TemplateForClasses{
DefaultSelenium browser;
#BeforeSuite
public void startBrowser(ITestContext itc){
browser = new DefaultSelenium(host,port,browser_type,url);
itc.setAttribute("browser",browser);
browser.start();
}
#AfterSuite
public void stopBrowser(ITestContext itc){
browser = (DefaultSelenium) itc.getAttribute("browser");
browser.stop();
}
//any other: #Before, #After methods
}
FirstGroupOfTests.java
//all tests classes will inherit preferences set in TemplateForClasses
public class FirstGroupOfTests extends TemplateForClasses{
public void FirstTest(ITestContext itc){
browser = (DefaultSelenium) itc.getAttribute("browser");
//browser.click("start");
}
}
idea:
start browser just once have tests
that run before every other tests(isBrowserRunning)
refer to browser from single test
This code was tested but currently I took it from the top of my head so possibly I will edit it tomorrow to make it more exact.
Update:
This result is based on testng.org documentation + some questions asked by me on stackoverflow + some answers found on several forums/groups
I must add I'm running testng programatically and I'm generating xml on the fly (as it is done on documentation.org). I am using it all in one package, I added package to the xml, included only classes Init + the ones that inherit from TemplateForClasses. If you need that xml, let me know.
I did this with Spring's dependency injection. And the init code is in a factory. I needed a way to have a Selenium instance shared not only between tests but between helper classes. Very seldom is selenium.someMethod() called directly in the tests. It more like helper.goToSomePage() or preferencesPage.changePassword(....).
It could be considered a bad idea to have a Selenium instance shared between tests, but the few bugs it brought were not that hard to find. The tests are run sequentially and the Selenium object need not be thread-safe. The state of the object must be kept consistent though.
For info, Spring is a Java framework and Dependency injection is only a part of it. Other DI frameworks like Guice can of course be used instead.
I too was stuck in the same problem for quite some time. I'll explain it in the simplest terms possible. Consider the following example:
Class A (contains the code selenium.start();)
|
|(inherited classes)
|--------class B }
|--------class C } Have some #Test methods
|--------class D }
Now everytime we run these test methods it will execute the code in the parent class constructor selenium.start(); Thats when the multiple browsers will all open up on your screen.
Now one by one the test methods will get executed - suppose tests in class B are executed they will be happening in one window, for class C another and so on.
So basically, all you have to do is remove the start() code from the parent constructor and put it somewhere in the classes B, C and D.
As long as you keep working with one selenium object everything will happen in one browser window. When you put start(); that browser will open (if it wasnt open) and a new session is created. stop(); and the session is terminated.
The flow of control goes like this=>
Class A, Class B
Class A, Class C
Class A, Class D
So if you can figure out a way to keep using the same selenium object with only 1 start() and 1 stop() for the entire execution sequence shown above, your test execution will happen in only one browser window.
If you put start() code in class A and stop code in each of B,C and D then you will have 3 windows open and one by one they will close as execution progresses.
If you put start() and stop() code individually in B,C and D then you will see one browser opening, executing test cases, closing. Another will then open, execute test cases for C, close etc.
Hope this helps. :-)