XCTest after test case? - xctest

I am writing integration tests with a docket printer and I need it to cut the docket after all the unit tests in a single suite are complete.
Other test frameworks I've used have a tearDownAfterClass type action, but XCTest doesn't seem to have that?
Is there anyway I can simulate this?

Other test frameworks I've used have a tearDownAfterClass type action, but XCTest doesn't seem to have that?
XCTest has exactly that feature. There are two versions of tearDown, one an instance method and one a class method:
- (void)tearDown; // this gets called after each test
+ (void)tearDown; // this gets called after all tests in the suite
Similarly, there are instance and class versions of setUp, so you can do setup work before each test or once before the suite runs.

There is a crude solution to this. It turns out that XCTest always runs tests in alphabetical order, so like:
/**
* Tests are run in alphabetical order, hence the Z so this runs last.
*/
- (void)testZTearDownAfterClass
{
// ...
}
The same would conversely be true about setUpBeforeClass:
- (void)test_setUpBeforeClass
{
// ...
}

Related

Instantiate XCTestCase subclass multiple times in a test run

I have an XCTestCase subclass EndpointIntegrationTests that contains integration tests that exercise the client application's endpoints against the backend.
We have a number of testing backend environments. They share the same databases, so the tests in EndpointIntegrationTests should work equally well on all of the backends.
I'd like to be able to instantiate multiple instance of EndpointIntegrationTests in a test run, initialising each (or configuring after initialisation) with the specific backend it should test. I'd then instantiate the suite once for each backend, so that all tests are run against all backends. Perhaps a bit like this…
func addTestCaseInstances() {
for environment in ["SIT01", "SIT02", "NFT"] {
let testCase = EndpointIntegrationTests(environment: environment)
addTestCaseInstance(testCase)
}
}
Is there a mechanism in XCTest to allow this? I've only ever seen XCTestCase subclasses be automatically instantiated by the test harness. The harness only instantiates each subclass once.
Thanks.

How to disable a parallel run for a specific SpecFlow scenario?

Is it possible to exclude a specflow scenario from parallel run?
I set up parallel run for all the assembly by doing this:
[assembly: Parallelize(Workers = 10, Scope = ExecutionScope.ClassLevel)]
in AssemblyInfo.cs file.
But now I need to exclude one specific scenario from parallel run. How can I do it?
One way to solve this is to use the NonParallelizable Attribute, provided by NUnit.
Example:
namespace Tests
{
[SetUpFixture]
public class TestsSetUpFixture
{
//setup the tests
}
[TestFixture]
[NonParallelizable]
public class TestFixture1
{
[Test]
public void TestFixture1_Test()
{
//do stuff in your test
}
}
}
NUnit provides this documentation:
This attribute is used to indicate that the test on which it appears
may not be run in parallel with any other tests. The attribute takes
no arguments and may be used at the assembly, class or method level.
When used at the assembly level, its only effect is that execution
begins on the non-parallel queue. Test suites, fixtures and test cases
will continue to run on the same thread unless a fixture or method is
marked with the Parallelizable Attribute.
When used on a test fixture or method, that test will be queued on the
non-parallel queue and will not run while other tests marked as
Parallelizable are being run.
Hope this helps.

How to use TestNg in Selenium WebDriver?

How to use TestNg in Selenium WebDriver? Explain me what is the usage of that.
I am new Learner in Selenium WebDriver
Hi TestNG can be defined as
1.TestNG is a testing framework designed to simplify a broad range of testing needs, from unit testing (testing a class in isolation of the others) to integration testing (testing entire systems made of several classes, several packages and even several external frameworks, such as application servers).
2.For official TestNG documentation Please Click Here
Before you can use TestNG with selenium you have to install it first.Talking in consideration that you are working with eclipse (any version)
1.There are various ways to install TestNG either follow this or this or simply go to Help/Eclipse MarketPlace. under Find type Test NG and click on the install
now how to use Test NG in eclipse with selenium
#BeforeTest
public void TearUP(){
// preconditions for sample test
// like browser start with specific URL
}
#Test
public void SampleTest(){
// code for the main test case goes inside
}
#AfterTest
public void TearDown1(){
// thing to done after test is run
// like memory realese
// browser close
}
Some information for above code
TestNG have various annotations for more info on annotation go to the above link
#BeforeSuite: The annotated method will be run before all tests in this suite have run.
#AfterSuite: The annotated method will be run after all tests in this suite have run.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
#AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the <test> tag have run.
#BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
#AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
#AfterClass: The annotated method will be run after all the test methods in the current class have been run.
#BeforeMethod: The annotated method will be run before each test method.
#AfterMethod: The annotated method will be run after each test method.
One of the primary usage of selenium is to test ui functionality, and as a testing framework testNg has many techniques to run and report the tests and can be leveraged for ui testing with selenium. One of the tools effectively use this is selion (https://github.com/paypal/selion).

How do you run one XCTestCase subclass's test method from inside another XCTestCase subclass's test method in XCode 7?

How do you run one XCTestCase subclass's test method from inside another XCTestCase subclass's test method in XCode 7?
I have a test suite for my point-of-sale app.
I have an XCTestCase subclass called "MathTest" which does various unit tests on math functions of the app. It also has a test method testTillMath that checks the register to see if the transaction totals all match up to expected values.
Then I have another XCTestCase subclass called "TicketBuildingTest" which has a test method called testCreateTickets that draws from an Excel spreadsheet data source, using whatever data is in the spreadsheet to assemble a specific batch of transactions into a special Core Data store specific to the test environment.
The testTillMath method will only succeed if testCreateTickets has first been run successfully.
How can I make testTillMath get run every time after testCreateTickets has finished?
I tried to #include MathTest.m from inside of TicketBuildingTest so that I could call testTillMath at the end of testCreateTickets, but XCode won't let me do that include. The build fails with the error, "linker command failed with exit code 1" due to "duplicate symbol _OBJC_CLASS_$_MathTest"
I realize there is likely to be more than one way to skin this cat; in PHPUnit I can specify a set of test methods to be run all in a row, in a certain order, running each test after the one before it completes. How can I do that in XCode?
You've deliberately introduced "test pollution", i.e. a situation where the success or failure of one test is dependent on the success or failure of another test. This is a bad practice. Tests should be independent of each other. That way you know that when a test fails, it's failing due to the functionality within your app that it's specifically testing—so you can track down that functionality and fix it. Debugging test pollution is a real ordeal, and you should avoid it at all costs.
Some testing frameworks (Rspec, for one; Cedar for another) randomize the order in which tests are run, precisely to discourage the kind of test coupling you describe.

Run Cucumber JVM tests manually

I have a bit of a special situation. Basically I have a unit test, annotated with #Test, and inside that test I need to execute a Cucumber JVM test class.
Why? Long story. Something to do with classloaders and RoboGuice, it's not very important but it does impose limits on what I can and cannot do.
Here's the test method:
#Test
public void runCucumberFeature() throws Exception {
Cucumber cucumber = new Cucumber(MyCucumberTest.class);
cucumber.run(new RunNotifier());
}
MyCucumberTest is a class I have created, and annotated like this:
//#RunWith(Cucumber.class)
#Cucumber.Options(format = {"pretty", "html:target/cucumber"}, strict=true)
public class MyCucumberTest {
// Empty, as required by Cucumber JVM
}
Why have I commented out the #RunWith annotation? Because if I don't, the Cucumber test runner will pick up the test and run it, which I don't want because I am running the test manually.
The problem is that the above doesn't work. It looks like Cucumber is finding the feature files, it is verifying that MyCucumberTest contains the #Givens etc, it even prints out the test as if it was running it.
But it doesn't. No code is executing inside the #Given, #When and #Then methods. I'm not sure why this is, but I have a vague idea that the Cucumber JVM test runner doesn't want to execute the code because the class isn't annotated with #RunWith.
Can anyone help?
I can't provide the solution you're looking for, but....
... have you considered tagging the test that you want to run manually (e.g. with #Manual)?
Then you could uncomment your #RunWith annototation and exclude the manual test by adding --tags ~#Manual to your Cucumber-JVM invocation.
In your manual JUnit invocation you could add --tags #Manual