Showing posts with label junit. Show all posts
Showing posts with label junit. Show all posts

Tuesday, September 18, 2018

How to use “on update CURRENT_TIMESTAMP” in H2 database?

Leave a Comment

I want my entity to have a modification timestamp whenever it is updated. mysql supports this using the following definition:

@Entity public class MyTable {     @Column(columnDefinition = "TIMESTAMP default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP")     private LocalDateTime thetime; } 

Problem: in my JUnit tests I want to use an embedded inmemory H2 database. And H2 does not support on update CURRENT_TIMESTAMP.

Question: how can I keep the column definition (as I will be running mysql in all cases except in automated tests)? And how can I workaround that in my h2 testing?

1 Answers

Answers 1

The official statement from the H2 people is that it is not supported and the workaround is to create a trigger. You can read this here https://github.com/commandos59/h2database/issues/491

Whatever you put in the "columnDefinition" it is provider specific. And since you have already mapped your entity with this specific column definition you are not leaving yourself much space to manouver.

There are several things you can do. Some of the things are hacks.

  1. Mix XML configuration for the tests. The XML configurationn of the Entities has higher priority than the annotations so you can actualy override the

    @Column(columnDefinition = "TIMESTAMP default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP") private LocalDateTime thetime

with H2 specific column definition.

  1. Another alternative agnostic of the Database is to leave your time generation to the application server layer and hook it to the @PrePersist @PreUpdate listeners on the entity

  2. If you insist to have your timestamp generated by the database you can do something similar to how the IDs are generated. Have some sort of dedicated object that reads the CURRENT_TIMESTAMP from the database and puts it the entty right before you persist, update.

Read More

Tuesday, July 17, 2018

Spring Boot JacksonTester custom serializer not registered

Leave a Comment

Trying to run the through Jackson library for some upcoming work. I've got the following test model:

Address.java

package com.example.domain;  import java.time.LocalDate;  import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle;  import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;  public class Address {      private String addressKey;     private String postalCode;     private String country;      @JsonSerialize(using = DateSerializer.class, as = String.class)     @JsonDeserialize(using = DateDeserializer.class, as = LocalDate.class)     private LocalDate dateEntered;      public String getAddressKey() {         return addressKey;     }      public void setAddressKey(String addressKey) {         this.addressKey = addressKey;     }      public String getPostalCode() {         return postalCode;     }      public void setPostalCode(String postalCode) {         this.postalCode = postalCode;     }      public String getCountry() {         return country;     }      public void setCountry(String country) {         this.country = country;     }      public LocalDate getDateEntered() {         return dateEntered;     }      public void setDateEntered(LocalDate dateEntered) {         this.dateEntered = dateEntered;     }      @Override     public int hashCode() {         return HashCodeBuilder.reflectionHashCode(this, false);     }      @Override     public boolean equals(Object obj) {         return EqualsBuilder.reflectionEquals(this, obj, false);     }      @Override     public String toString() {         return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE, false);     } } 

and a custom serializer for the dateEntered field:

DateSerializer.java

package com.example.domain;  import java.io.IOException; import java.time.LocalDate; import java.time.format.DateTimeFormatter;  import org.springframework.boot.jackson.JsonComponent;  import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider;  @JsonComponent public class DateSerializer extends JsonSerializer<LocalDate> {     @Override     public void serialize(LocalDate lc, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)             throws IOException, JsonProcessingException {         String date = lc.format(DateTimeFormatter.ofPattern("dd MM yyyy"));         jsonGenerator.writeString(date);     } } 

I've put together the following test, leveraging the @JsonTest annotation to check if the serializer class is doing what i think it should:

AddressTest.java

@JsonTest @RunWith(SpringRunner.class) public class AddressTest {  @Autowired private JacksonTester<Address> json;      @Test     public void test_Address_serialisation_dateEnteredSerialised() throws Exception {         final Address address = getTestAddress();          assertThat(json.write(address))             .hasJsonPathStringValue("@.dateEntered")             .extractingJsonPathStringValue("@.dateEntered")             .isEqualTo("01 05 2018");     }      private Address getTestAddress() {         final Address testAddress = new Address();         testAddress.setAddressKey("testAddressKey");         testAddress.setCountry("testCountry");         testAddress.setPostalCode("testPostalCode");         testAddress.setDateEntered(LocalDate.of(2018, 5, 1));         return testAddress;     }  } 

When i run the serialize test, I get this in console:

com.fasterxml.jackson.databind.JsonMappingException: Invalid definition for property dateEntered (of type 'Lcom/example/domain/Address;'): Can not refine serialization type [simple type, class java.time.LocalDate] into java.lang.String; types not related  at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:284) at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1110) at com.fasterxml.jackson.databind.SerializerProvider.reportBadPropertyDefinition(SerializerProvider.java:1180) at com.fasterxml.jackson.databind.ser.PropertyBuilder.buildWriter(PropertyBuilder.java:101) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._constructWriter(BeanSerializerFactory.java:816) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanProperties(BeanSerializerFactory.java:610) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:399) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:282) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:234) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:168) at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1308) at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1279) at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:536) at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:743) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:330) at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1427) at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1158) at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1031) at org.springframework.boot.test.json.JacksonTester.writeObject(JacksonTester.java:116) at org.springframework.boot.test.json.AbstractJsonMarshalTester.write(AbstractJsonMarshalTester.java:133) at com.example.domain.AddressTest.test_Address_serialisation_dateEnteredSerialised(AddressTest.java:68) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 

From what I could gather, adding @JsonComponent to the classwould allow it to be picked up and registered when used in conjunction with @JsonTest but based on this it doesnt seem like its being scanned and added. Am i missing a step in the test or src code? Its worth noting that the deserialiser is set up the same way(it toStrings the date in a particular format) and it works fine

1 Answers

Answers 1

Specifying as = ... within @JsonSerialize is rarely needed, especially when you also specify using = ....

Quoted from the javadoc of @JsonSerialize.as:

...
Note: if using is also used it has precedence (since it directly specifies serializer, whereas this would only be used to locate the serializer) and value of this annotation property is ignored.

In your case: Specifying as = String.class seems to be the culprit of the not found JSON serializer.

If you omit it and in your Address class just write

@JsonSerialize(using = DateSerializer.class) @JsonDeserialize(using = DateDeserializer.class) private LocalDate dateEntered; 

then the DateSerializer is found and the AddressTest runs fine without exception.

Read More

Saturday, September 16, 2017

How does dependency injection work in Cucumber?

Leave a Comment

I have been trying to inject webdriver into the steps. I have used this instructions and it works well.

The idea is to inject WebDriver into steps classes as a service. At the initial step, you need to add the following dependency.

<dependency>     <groupId>info.cukes</groupId>     <artifactId>cucumber-spring</artifactId>     <version>1.2.5</version>     <scope>test</scope> </dependency> 

There are three main classes which are involved in the dependency injection. Here we introduce them one by one.

enter image description here

BaseUtil

BaseUtil is the class which has an attribute for WebDriverof Selenium. The class is quite simple:

public class BaseUtil {   private WebDriver driver;   public WebDriver getDriver() {return driver;}   public void setDriver(WebDriver driver) { this.driver = driver;} } 

Hook

The Hook class contains @Before, @After. The method testInitialier() is responsible to load the the webDriver file and create an instance, while the method testTearDown() is responsible for closing the browser.

    public class Hook extends BaseUtil{      BaseUtil base;       @Before     public void testInitializer(){         File file = new              File(IgniteTaskApplication.class.getClassLoader().getResource("driver/chromedriver.exe").getFile());         String driverPath=file.getAbsolutePath();         System.out.println("Webdriver is in path: "+driverPath);         System.setProperty("webdriver.chrome.driver",driverPath);         base.setDriver(new ChromeDriver());     }      public Hook(BaseUtil base) {         this.base = base;     }      @After     public void tearDownTest(){         base.getDriver().close();     } } 

Steps

And the steps class contains the steps which came from compiled features file. To compile the feature file in Eclipse you need to have Eclipse-Cucumber plugin installed in your Eclipse.

public class ClickButton_Steps extends BaseUtil{     BaseUtil base;      public ClickButton_Steps(BaseUtil base){         super();         this.base=base;     }      @When("^I clcik on the button$")     public void i_clcik_on_the_button() throws Throwable {         cb=new ClickButtonPage(base.getDriver());         cb.navigator();     }          // The other steps ... } 

How do i run it?

Open the feature file -> Run as -> Run with Junit

Question

I am wondering what is the order of running methods in a way which it leads to dependency injection?

I guess the order is as following:

  1. Junit calls @Before method which is testInitializer()
  2. The testInitializer()is in Hook class so it needs to make an instance of Hook class.
  3. It leads to call the constuctor of the Hook class.

But, i cannot understand the rest of the steps. Maybe even it does not true at all. I mean, I have a functional code but i cannot explain how it works?

0 Answers

Read More

Tuesday, June 13, 2017

Selenium3.4.0-Python3.6.1 : In Selenium-Python binding using unittest how do I decide when to use self.assertIn or assert

Leave a Comment

I am working with Selenium 3.4.0 with Python 3.6.1. I have written a script following the Python documentation through unittest module which is a built-in Python based on Java’s JUnit using geckodriver 0.16.1 and Mozilla Firefox 57.0 on Windows 8 Pro machine, 64 bit OS, x-64 processor. In my test method test_search_in_python_org() I have the following lines which works well:

    def test_search_in_python_org(self):       driver = self.driver       driver.get("http://www.python.org")       self.assertIn("Python", driver.title)       elem = driver.find_element_by_name("q")       elem.send_keys("pycon")       elem.send_keys(Keys.RETURN)       assert "No results found." not in driver.page_source 

When I am asserting the "page title" I am using: self.assertIn("Python", driver.title)

But, when I am asserting a string (my assumption), within the page source I am using: assert "No results found." not in driver.page_source

My question is what are the factors/conditions which decides whether I should use self.assertIn or simply assert?

Any suggestions or pointers will be helpful.

2 Answers

Answers 1

Looking at the Python unittest documentation and also recalling from the bunch of Django unittests that I once had to do here are my findings.

USE CASE:

First thing that is the most simple thing and in my opinion the biggest difference between the two, it where you can use each assert command. They are both interchangeably usable in the case of a test class, however, in order to use the assertIn command, the unittest library is needed. So, say I want to know if h is in hello, a simple way to do it through this command is:

class MyTestCase(unittest.TestCase):     def is_h_in_hello(self):         self.assertIn("h", "hello") 

and then I need to run tests, that is through unittest.main() in this example, in order to get my answer. But using the assert command, it is much easier for me to find out that h is actually in hello. Which is very simply done like so:

assert "h" in "hello" 

But essentially, both will give me the same result, however what distinguishes the two is the simplicity of use in the second method.

RESULTS:

The second difference I found was the readability of the results and the message on Python Shell. The unittest library is designed so that the commands are very specific and so if a test fails, you will receive a very clear message saying what went wrong. So say now you want to see if b is in hello. Doing it through the class method (simply changing "h" to "b", the message we get after running the test is:

AssertionError: 'b' not found in 'hello'  ---------------------------------------------------------------------- Ran 1 test in 0.038s  FAILED (failures=1) 

So it very clearly tells you: 'b' not found in 'hello', which is very convenient for you to see what exactly is the problem. But say you do the same process through the assert command. The error message generated is something like:

Traceback (most recent call last):   File "<pyshell#2>", line 1, in <module>     assert "b" in "hello" AssertionError 

Although it tells you that the error type (AssertionError), and the traceback, however it does not specifically tell you that "b" is NOT in "hello". In this simple case, it is very easy to look at the traceback and say oh, there's no b in hello! However in more complicated cases, it might be tricky to see why this error message was generated.

Overall, the two methods are very similar and will get you the result you want, but essentially it comes down to the little differences here and there, like how can you use less lines of code to get to the results and how straight-forward the Shell messages are.

Answers 2

In my opinion, assert is the built-in keyword in python which tells internal state of program. In other words, with the assert keyword, you can tell your code behavior. In your case, you should not use assert in testcase.

Read More

Tuesday, September 27, 2016

Mocking method calls using power mockito - org.powermock.api.mockito.ClassNotPreparedException

Leave a Comment

I have an image loader class and i need to test some static methods in it. Since Mockito does not support static methods i switched to Power Mockito. But the static method i am testing has a method call

 Base64.encodeToString(byteArray, Base64.DEFAULT); 

To mock this i am using mockStatic method as below with @PrepareForTest annotation.

 PowerMockito.mockStatic(Base64.class); 

But Android studio is returning me still returning me an error as below.

org.powermock.api.mockito.ClassNotPreparedException: The class android.util.Base64 not prepared for test. To prepare this class, add class to the '@PrepareForTest' annotation.

Below is my complete code.

Code to be tested:

import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Base64; import android.widget.ImageView;    public static String convertBitmapToBase64(Bitmap imageBitmap, boolean withCompression) {     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();     imageBitmap.compress(Bitmap.CompressFormat.PNG, 120, byteArrayOutputStream);     byte[] byteArray = byteArrayOutputStream.toByteArray();     return Base64.encodeToString(byteArray, Base64.DEFAULT); } 

Test class code

import android.graphics.Bitmap; import android.util.Base64; import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.testng.annotations.Test;  @RunWith(PowerMockRunner.class) @PrepareForTest({Base64.class}) public class ImageLoaderTest  { @Test    public void testConvertBitmap(){     byte[] array = new byte[20];     PowerMockito.mockStatic(Base64.class);     PowerMockito.when(Base64.encodeToString(array, Base64.DEFAULT)).thenReturn("asdfghjkl");     Bitmap mockedBitmap= PowerMockito.mock(Bitmap.class);     String output = ImageLoaderUtils.convertBitmapToBase64(mockedBitmap);     assert (!output.isEmpty()); } 

}

Gradle dependencies

testCompile 'junit:junit:4.12' testCompile 'org.powermock:powermock:1.6.5' testCompile 'org.powermock:powermock-module-junit4:1.6.5' testCompile 'org.powermock:powermock-api-mockito:1.6.5' 

2 Answers

Answers 1

Short answer you can't. Here from the FAQ:

What are the limitations of Mockito

  • Cannot mock final classes
  • Cannot mock static methods
  • Cannot mock final methods - their real behavior is executed without any exception. Mockito cannot warn you about mocking final methods so be vigilant.

Further information about this limitation:

Can I mock static methods?

No. Mockito prefers object orientation and dependency injection over static, procedural code that is hard to understand & change. If you deal with scary legacy code you can use JMockit or Powermock to mock static methods.

If you want to use PowerMock try like this:

@RunWith(PowerMockRunner.class) @PrepareForTest( { Base64.class }) public class YourTestCase {     @Test     public void testStatic() {         mockStatic(Base64.class);         when(Base64.encodeToString(argument)).thenReturn("expected result");     } } 

More on powermock test sample

Answers 2

Really trivially, I think you're calling prepareForTest incorrectly. It should be prepareForTest(Base64.class) not prepareForTest({Base64.class}) (note the squiggly braces in your code). Given the error you're getting, I think that's relevant.

Read More

Tuesday, June 21, 2016

Can JMockit work with scala?

Leave a Comment

I googled little bit and it seems for me that it's possible. But when I tried like this:

class Calc {   def sum(first: Int, second: Int) = {     first + second   } } 

And "test" class:

class CalcTest {   @Test   def testSum(@Mocked test: Calc) {     new NonStrictExpectations() {{       test.sum(2, 3)       times = 1       result = Int.box(5)     }}     Assert.assertEquals(5, test.sum(2, 3))   } } 

I have an exception:

java.lang.IllegalAccessError: tried to access class mockit.Invocations from class com.kvg.client.CalcTest$$anon$1 at com.kvg.client.CalcTest$$anon$1.(CalcTest.scala:11) at com.kvg.client.CalcTest.testSum(CalcTest.scala:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Can JMockit work with with scala? And if it can what am I doing wrong?

0 Answers

Read More

Thursday, April 28, 2016

How to limit BuildShip (gradle eclipse) integrated functionality?

Leave a Comment

Now that I am using gradle for all of my new development, I'm running into issues with BuildShip features I really don't want.

For instance, when I hit the Run hotkey when I have a unit test open in Eclipse, I only want it to run as a JUnit test, alone. But Gradle has inserted its own hooks and option, which means extra clicking or keypresses beyond the one-stroke hotkey I have assigned to Run that I can tell it I want JUnit. (The gradle test option actually runs all tests, which takes minutes.).

Question: Is there a way to remove this hook in gradle without diving into the source code and ripping out functionality myself?

This isn't the only interference (interfering with run last is another), but it's my #1 annoyance about BuildShip.

"run as"

Essentially, I want this popup to stop happening.

1 Answers

Answers 1

Indeed you cannot change the available launchers prompt but you can change the default hotkeys related to each launcher and directly use the one you prefer.

From Windows > Preferences > General > Editor > Keys you can get the list of available hot-key mappings. Filter the (long) list by typing test as show below:

enter image description here

As you can see you have several mappings for running JUnit tests: Gradle, JUnit runner, Maven.

The default configuration for JUnit runner is Alt+Shift+X,T, not really user friendly I would say.

I changed it to a more concise Alt+U down in the Binding option and applied the changes. Now you can run any JUnit test on its open editor windows without any prompt, simply type Alt+U and the JUnit runner will be triggered automatically for that single unit test.

Read More

Tuesday, April 26, 2016

JUnit Reports — Test Method Descriptions

Leave a Comment

I am trying to see if there is a way to include "descriptive text" in my junit reports by way of javadocs. JUnit 4 doesnt seem to support the 'description' attribute for the @Test annotation like TestNG does.

So far from what I have researched there is only one tool out there called javadoc-junit (http://javadoc-junit.sourceforge.net/). However I could not get this to work since it seems to be incompatible with Junit 4.

What I want is some way to provide a sentence or two of text with my each test method in the JUnit report. JavaDoc is no good since the target audience will have to swtich between JavaDoc and the Junit Report to see documentation and/or test stats.

Anyone know of anything else I could use with minimal effort?

Best, Ray J

4 Answers

Answers 1

There's also rather recent solution called Allure. That's a Java-based test execution report mainly based on adding supplementary annotations to the code. Existing annotations include:

  • custom description: @Description("A cool test")
  • grouping by features or stories: @Features({"feature1", "feature2"}), @Stories({"story1", "story2" })
  • marking methods executed inside test case as steps: @Step (works even for private methods)
  • attachments: @Attachment(name = "Page screenshot", type = "image/png")

See their wiki and example project for more details.

Answers 2

I don't put javadocs in JUnit tests. I usually make the name of the method descriptive enough so it's as good as or better than any comment I could come up with.

Answers 3

In JUnit 5 there is a way to annotate every test with a @DisplayName. The declared test classes can have text, special characters and emojis.

The declared text on each test is visible by test runners and test reports.


The Javadoc says:

public @interface DisplayName

@DisplayName is used to declare a custom display name for the annotated test class or test method. Display names are typically used for test reporting in IDEs and build tools and may contain spaces, special characters, and even emoji.

And the User Guide:

import org.junit.gen5.api.DisplayName; import org.junit.gen5.api.Test;  @DisplayName("A special test case") class DisplayNameDemo {      @Test     @DisplayName("Custom test name containing spaces")     void testWithDisplayNameContainingSpaces() {     }      @Test     @DisplayName("╯°□°)╯")     void testWithDisplayNameContainingSpecialCharacters() {     }      @Test     @DisplayName("😱")     void testWithDisplayNameContainingEmoji() {     } } 

Answers 4

I could imagine, that the Framework for Integrated Tests (FIT) would be a nice and clean solution.

What does FIT do?
FIT is a framework that allows to write tests via a table in a Word document, a wiki table or an html table.
Every character outside of a table is ignored by FIT and let you enter documentation, description, requirements and so on.

How does on of these tables look like?

Imagine a function MyMath.square(int) that squares it's input parameter. You have to build a so called Fixture, being an adapter between your MyMath and the following table:

class.with.Fixture.Square x    square() 2    4 5    25 

The first column describes input values, the second the expected result. If it's not equal, this field is marked as red.

How does a Fixture look like?
For the given example, this would be the correct fixture:

package class.with.Fixture // Must be the same as in the fist row of the table  public class Square extends Fixture {     public int x; // Must be the same as in the second row     public int square() { // Must be the same as in the second row         return MyMath.square(x);     } } 

Probably, you can use FIT for your requirements.
Feel free to comment my answer or edit your question for more information!

Read More