ErrorCollector in Jbehave story - jbehave

The ErrorCollector rule allows execution of a test to continue after the first problem is found (for example, to collect all the incorrect rows in a table, and report them all at once).
I try to use org.junit.rules.ErrorCollector with Jbehave story but after execution, JBehave says "All the tests passed" even though there are some failures and the ErrorCollector() collected them. JBehave should say some steps failed.
In JUnit it's ok:
public static class UsesErrorCollectorTwice {
#Rule
public ErrorCollector collector= new ErrorCollector();
#Test
public void example() {
String x = [..]
collector.checkThat(x, not(containsString("a")));
collector.checkThat(y, containsString("b"));
}
}
But in jbehave:
Scenario: S-1
Given check something
....
#Given("check something")
public void checkLoggedIn() {
loginSteps.check_that();
}
......
import org.hamcrest.Matchers;
import org.junit.rules.ErrorCollector;
import org.junit.Rule;
....
#Rule
public ErrorCollector collector= new ErrorCollector();
....
#Step
public void check_that() {
collector.checkThat("Error example", navigationMenuPanel.isUserSignedIn(), Matchers.is(false));
collector.checkThat("User has not been logged-in yet!", navigationMenuPanel.isUserSignedIn(), Matchers.is(true));
collector.addError(new Throwable("Shit error happen"));
collector.checkThat("It'wrong", 1, Matchers.equalTo(3));
}
This story always passed.

Related

Will Junit execute the #Test case when the code in the #before Section fails?

I'm new to Junit.
If I execute something in the #before part, and my code fails. e.g. I want to make a server connection, but it fails for some reason.
Will Junit execute my Test in the #Test section even if the #before fails? Because then my test would fail because I haven't a server connection. How can I handle it if its the case?
You can try this out with a basic junit.
public class SamplePlayTest {
#Before
public void setup() {
System.out.println("Before called");
throw new RuntimeException();
}
#Test
public void test() {
System.out.println("Test case called");
}
}
This gives output as
Before called
And fails with error java.lang.RuntimeException. Test case called is not printed.

When more than one tests added to rest controller test why am I getting WebApplicationContext is required?

This is very funny. When I ran my controller test with more than one tests I am getting the following error when i run it with maven, but works fine in eclipse Junit.java.lang.IllegalArgumentException: WebApplicationContext is required
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder.<init>(DefaultMockMvcBuilder.java:43)
at org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup(MockMvcBuilders.java:46)
at com.akrilist.rest.web.akripost.controller.AbstractRestControllerTest.setup(AbstractRestControllerTest.java:32)
at com.akrilist.rest.web.akripost.controller.AutoPostControllerTest.setup(AutoPostControllerTest.java:36) Then I ran one test commenting the other alternately (commented testA then run testB, then commented testB then run testA) both are passing. I have no idea what is happening when I put both of then are active tests. if any of you have clue please let me know. I have put my classes here.
AbstractRestControllerTest
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { TestRestServiceConfig.class, WebAppConfig.class })
#WebAppConfiguration
public abstract class AbstractRestControllerTest {
protected MockMvc mockMvc;
#Autowired
protected WebApplicationContext webApplicationContext;
/*#Inject
protected UserAccountService userAccountServiceMock;*/
#Before
public void setup() {
/* Mockito.reset(userAccountServiceMock);*/
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
AutoPostControllerTest
public class AutoPostControllerTest extends AbstractRestControllerTest {
#Autowired
private AutoPostService autoPostServiceMock;
#Autowired
private AutoPostConverter autoPostConverterMock;
#Before
public void setup() {
// Mockito.reset(autoPostServiceMock);
// Mockito.reset(commentPostRepositoryMock);
super.setup();
}
#Test
public void testValidationErrorForNullProfileId() throws Exception {
String description = TestUtil.createStringWithLength(501);
AutoPost autoPost = new TestAutoPostBuilder().description(description).buildModel();
mockMvc.perform(post("/auto/post").contentType(TestUtil.APPLICATION_JSON_UTF8).content(TestUtil.convertObjectToJsonBytes(autoPost))).andExpect(status().isBadRequest())
.andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
// .andExpect(jsonPath("$[]", hasSize(1)))
.andExpect(jsonPath("$.type", is("validation failure")));
verifyZeroInteractions(autoPostServiceMock);
}
#Test
public void testGet_shouldReturnPost() throws Exception {
String description = TestUtil.createStringWithLength(501);
String postId = TestUtil.createStringWithLength(16);
Integer profileId = 123456;
TestAutoPostBuilder testAutoPostBuilder = new TestAutoPostBuilder();
AutoPost post = testAutoPostBuilder.postId(postId).description(description).profileId(profileId).buildModel();
when(autoPostServiceMock.get(postId)).thenReturn(post);
when(autoPostConverterMock.convertTo(post)).thenReturn(testAutoPostBuilder.buildDto());
mockMvc.perform(get("/auto/post/" + postId).contentType(TestUtil.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.postId", is(postId))).andExpect(jsonPath("$.profileId", is(profileId))).andExpect(jsonPath("$.links", hasSize(1)));
verify(autoPostServiceMock, times(1)).get(anyString());
verifyNoMoreInteractions(autoPostServiceMock);
}
}
I fixed this issue. It was because of parallel configuration of maven-surefire-plugin. I changed its value to 'classes', so the issue is over. There are two ways we can fix this issue. One is
<parallel>classes</parallel>
<threadCount>10</threadCount>
other way annotating the test class with #net.jcip.annotations.NotThreadSafe that required sequential execution.

Test with AutoData from base test fixture isn't run

I use Autofixture 3.21.0 and AutoFixture.NUnit2 3.21.0 along with NUnit 2.6.3 and Resharper 8.2.3 runner.
I have implemented the generic base test fixture which contains a common set of tests for several production classes. It's something like the following:
[TestFixture]
public class TestsBase<T>
{
[Test]
public void Test_in_base_class()
{
Assert.Pass();
}
[Test, AutoData]
public void Test_in_base_class_with_autodata( T obj )
{
// this test is not run !!!
Assert.NotNull( obj );
}
}
One example concrete test fixture class which inherits from base test fixture class can be implemented as shown below:
[TestFixture]
public class DerivedTests : TestsBase<string>
{
[Test]
public void Test_in_derived_class()
{
Assert.Pass();
}
[Test, AutoData]
public void Test_in_derived_class_with_autodata( string obj )
{
Assert.NotNull( obj );
}
}
When I run this derived test fixture using R# 8.2.3 runner, test method from base class which is attributed with AutoDataAttribute (named Test_in_base_class_with_autodata) is not run. All other test methods are invoked as expected but that from base class with AutoDataAttribute.
Have you had the same problem? Is it AutoFixture.Nunit2 bug? Is there a workaround for this issue? Please for help.

How to make NUnit stop executing tests on first failure

We use NUnit to execute integration tests. These tests are very time consuming. Often the only way to detect a failure is on a timeout.
I would like the tests to stop executing as soon as a single failure is detected.
Is there a way to do this?
Using nunit-console, you can achieve this by using the /stoponerror command line parameter.
See here for the command line reference.
For nunit-console v3, it changes to --stoponerror (see here for the command line reference).
I'm using NUnit 3 and the following code works for me.
public class SomeTests {
private bool stop;
[SetUp]
public void SetUp()
{
if (stop)
{
Assert.Inconclusive("Previous test failed");
}
}
[TearDown]
public void TearDown()
{
if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
{
stop = true;
}
}
}
Alternatively you could make this an abstract class and derive from it.
This is probably not the ideal solution, but it does what you require i.e. Ignore remaining tests if a test has failed.
[TestFixture]
public class MyTests
{
[Test]
public void Test1()
{
Ascertain(() => Assert.AreEqual(0, 1));
}
[Test]
public void Test2()
{
Ascertain(() => Assert.AreEqual(1, 1));
}
private static void Ascertain( Action condition )
{
try
{
condition.Invoke();
}
catch (AssertionException ex)
{
Thread.CurrentThread.Abort();
}
}
}
Since TestFixtureAttribute is inheritable, so you could potentially create a base class with this attribute decorated on it and have the Ascertain protected Method in it and derive all TestFixture classes from it.
The only downside being, you'll have to refactor all your existing Assertions.

Run Current Junit Test in GWTTestCase

I have a JUnit test that I run on one class, but I recently wrote an emulated version for GWT. Since the specification is the same, I would like to use the same test case, but I want it to run in the GWT environment, which would typically be accomplished by extending GWTTestCase.
I really want to avoid any copy/paste nonsense, because there are likely to be added tests in the future, which I should not be burdened with copying later.
How can I import/inherit my standard unit test to be run as either a regular test case or a GWT test case?
I have found the solution to this problem.
If you extend the original test with GWTTestCase, you can override getModuleName to return null. This tells GWTTestCase to run as a normal pure java test (no translation at all).
You can then extend this test case with one that overrides getModuleName to return a module name, and the same tests will be run with translation.
Basically:
public class RegularTest extends GWTTestCase {
#Override
public String getModuleName() { return null; }
public void testIt() {...}
}
...and the GWT version...
public class GwtTest extends RegularTest {
#Override
public String getModuleName() { return "some.module"; }
}
The downside to this is that it forces you to use JUnit3 style tests, which I find a little annoying, but it beats the alternative.
I think there is no easy way .. But you can extract an interface of your junit test, gwt test case and junit test case implements this interface. You can create a third class for implementation, all test call methods of gwt test case and junit test are delegated to this implementation class.
public interface IRegularTest {
public void testSomething();
public void testSomething2();
}
public class RegularTestImpl implements IRegularTest {
public void testSomething(){
// actual test code
}
public void testSomething2(){
// actual test code
}
}
public class RegularTest extends TestCase implements IRegularTest {
IRegularTest impl = new RegularTestImpl();
public void testSomething(){
impl.testSomething
}
public void testSomething2(){
}
}
public class GwtTest extends TestCase implements IRegularTest {
IRegularTest impl = new RegularTestImpl();
public void testSomething(){
impl.testSomething
}
public void testSomething2(){
}
}