I am new to xunit and I would like to impose the following traits in all of the tests. The value of the trait Category can be either Unit or Integration. The value of Requirement trait can be anything as long as it is there. Tests are in located in different projects but in the same solution.
[Fact]
[Category, "Unit"]
[Requirement, "SomeRequirement"]
public void testMethod()
{
}
you can use the trait attribute.
Trait("Scope", "Unit")
Related
I am creating a class to store the tests of all DTO classes, but currently I only manage to cover 10% of the coverage. I need to know how to do the #Tests for the DTOs.
My DTO:
#Data
#NoArgsConstructor
public class ActivityDTO {
private Integer id;
private Integer version;
#JsonProperty("working_days")
private MonthWorkingDays workingDays;
}
My Test class:
#Test
public void ActivityDTOTest() {
ActivityDTO obj = BeanBuilder.builder(ActivityDTO.class).createRandomBean();
}
This is the coverage:
My problem: I don't know how to test the DTO class, I'm testing with assertEquals but I don't know how to apply it. Can someone put what the Test class would be like for this DTO class and thus be able to replicate it in the other classes?
This might be subjective, but in general you should not test to increase the coverage, instead you should always think "what exactly" the test checks.
In a nutshell, there can be two things to be tested:
A state of the object
A behavior
Most of the tests usually (arguably, but at least this is what I usually do in my project) tend to check the behavior that is technically implemented as a business logic inside the methods.
Since the DTOs do not really have methods with the logic, you can only test the state of the object.
Another idea: there is no point in checking the code that you haven't written. So yes, following your example in the question, putting lombok annotations will generate some getters/setters/constructors - but its not your code, the proper handling of these annotations was supposed to be checked by lombok team itself.
What you can do if you really want to test DTOs is generate the one with some default values and check that its internal state indeed matches the expected. Something like this:
public class ActivityDTO {
private Integer id;
private Integer version;
// getters / setters maybe
}
#Test
public void test_state_is_correct() {
ActivityDTO underTest = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
assertThat(underTest.getId(), equalTo(SAMPLE_ID));
assertThat(underTest.getVersion(), equalTo(SAMPLE_VERSION));
}
#Test
public void test_equals_two_objects_with_same_values() {
ActivityDTO underTest = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
assertThat(underTest, equalTo(new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION));
}
#Test
public void test_equals_two_objects_with_different_id() {
ActivityDTO underTest = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
assertThat(underTest, not(equalTo(new ActivityDTO(ANOTHER_SAMPLE_ID, SAMPLE_VERSION));
}
#Test
public void test_equals_two_objects_with_different_version() {
ActivityDTO underTest = new ActivityDTO(SAMPLE_ID, SAMPLE_VERSION);
assertThat(underTest, not(equalTo(new ActivityDTO(SAMPLE_ID, ANOTHER_SAMPLE_VERSION));
}
... test for toString()... and hashCode maybe, etc.
This will make the coverage tool happy for sure, but the real question is will it make your code better (more robust and less buggy, etc)?
One thing for sure - these tests are time consuming, boring, and probably give less value to the project. To overcome the frustration of the programmers who absolutely need to write these tests there are even tools for automatic testing of these simple java beans (DTO can be viewed as a java bean), to name a few:
https://github.com/codebox/javabean-tester
https://code.google.com/archive/p/junit-javabean-runner/
http://javabeantester.sourceforge.net/
Now the entirely different story is if you test the behavior of some service or DAO that, say, generates the DTO - these tests whether they're unit or integration tests are really needed. They'll also increase the coverage of the project (and maybe even will cover the code of the DTO, although its not their primary goal), but I would suggest to start writing these tests first.
I don't know what is the best practice but AFAIK you should exclude the DTO classes from the configuration and you don't have to write unit test for them.
If you are using JaCoCo plugin, you better check this out: How to exclude certain classes from being included in the code coverage? (Java)
I've updated Specflow from the 3.0.225 to the 3.1.62 and I received the error Tests_Integration_MSTestAssemblyHooks: Cannot define more than one method with the AssemblyInitialize attribute inside an assembly.
The reason is obviously that I'd had the [AssemblyInitialize] attribute in my project already. How can I fix it?
The reason is that Specflow generates another file in the background which has the AssemblyInitialize/AssemblyCleanup hooks defined. In order to fix that one should use the hooks provided by Specflow, namely BeforeTestRun/AfterTestRun. Like this:
[Binding] // add the Binding attribute on the class with the assembly level hooks
public abstract class SeleniumTest
{
// it used to be [AssemblyInitialize]
[BeforeTestRun]
public static void AssemblyInitialize(/* note there is no TestContext parameter anymore */)
{
// ...
}
// it used to be [AssemblyCleanup]
[AfterTestRun]
public static void AssemblyCleanup()
{
// ...
}
}
I'm trying to separate my gradle/spock tests into two groups:
unit tests
integration tests
My attempt was with jUnit's #Category. In build.gradle I created task for integration/e2e tests:
task e2eTest(type: Test) {
useJUnit {
includeCategories 'com.foo.bar.baz.E2ESpec'
}
}
And marked my base abstract class with #Category(E2ESpec), but it doesn't work.
I've noticed that inheritance works, but only with single level inheritance:
#Category(E2ESpec)
abstract class AbstractSpec {...}
class ActualSpec extends AbstractSpec {...}
but doesn't work for cases like:
#Category(E2ESpec)
abstract class AbstractSpect {...}
abstract class AnotherAbstractSpec extends AbstractSpec {...}
class ActualSpec extends AnotherAbstractSpec {...}
Any idea how to fix it?
PS. I've many classes extending AbstractSpec and new classes appears, so I don't want #Category on each spec. Maybe pure gradle solution exists?
Create a new sourceset for integration tests, with a corresponding task. See How do I add a new sourceset to Gradle?
I just got some feedback about a job application Java coding exercise. They did not like the solution and two problems where stated in the feedback (which I'm very grateful for as it's very rare feedback is given):
I did not use TDD approach, apparently.
I overused static methods, I know static methods are anti OO but I only used them in validation and util type methods.
So two questions here:
What are the possible tell-tale signs of not using TDD approach?
What coding style or patterns can be an alternative to static methods?
Following the first two responses I have another question.
Do you agree that using static methods is only bad when it limits the testability of your code and not in them selves bad.
So going back to my job application exercise solution if the static methods do not limit the testability of my code is it still bad to use? my validate method was very simple 'Validator.notNull(p,"paramName")' now why would I ever want to mock that?
Many thanks.
A tell-tale sign of not using TDD is usage of static methods and static class members for collaborators. You cannot override a static method, so you cannot substitute a mock to test the class using such methods in isolation.
Instead of using static collaborators or static methods on the collaborators, you can use dependency injection. In a simple coding exercise you would inject dependency via a constructor or via the setters by hand. In the real life you can use one of available dependency frameworks.
Your static Validaton method seems something that should be part of an object to me.
Say you have an class Drink
public class Drink
{
private readonly string _name;
private readonly double _temperature;
public Drink(string name, double temperature)
{
_name = name;
_temperature = temperature;
}
}
Your businesslogic would be able to instantiate all kinds of drinks, 7up, cola, whatever. You'd like to make sure that a drink has the appropriate temperature to drink it, so you have the need for a Validate method. You could follow your approach:
public void TakeAZip()
{
if (Validation.HasAppropriateTemp)
{
// implement drink
}
}
'
Alternatives for static classes
That way you have an hard dependency on your static Validation class.
Alternatively you could make use of dependency injection.
public void TakeAZip(ITemperatureValidator validator)
{
if (validator.HasAppropriateTemp)
{
// implement drink
}
}
If more convenient you could also choose to pass the Validator via the constructor
private readonly string _name;
private readonly double _temperature;
private ITemperatureValidator _validator;
public Drink(
string name,
double temperature,
ITemperatureValidator validator)
{
_name = name;
_temperature = temperature;
_validator = validator;
}
Now you can mock the behavior of your validator and you can isolate your Drink class from all external behavior.
In MBUnit I can annotate my Test class with a Factory and multiple getter returning an oracle/sql/mysql connection string which can be obtained by every test method in the test class.
How can I do this with the Unit Test Project for Visual Studio 2010?
e.g. I am not allowed to inherit from TestContext and pass that object to my ClassInit method?
[ClassInitialize()]
public static void MyClassInitialize(MyContextDerivedFromTextContext testContext)
{
}
I do not want to hardcode-annotate my TestMethods with such an attribute:
[DataSource("System.Data.SqlClient", "Data Source=.\\SQLEXPRESS;Initial Catalog=STM;Integrated Security=True;Pooling=False", "CustomerTable", DataAccessMethod.Sequential), TestMethod]
public void TestMethod1()
{
//
// TODO: Add test logic here
//
}
I want this:
public void TestMethod1(String testconnectionStringOracleORMySQLORMSSQLetc...)
{
//
// TODO: Add test logic here
//
}
I think you're out for some disappointment. MSTest supports data driven tests as you've already shown but it sucks compared to other test frameworks.
The only approach I can think of that might do what you want is to store your connection strings in an XML file and that as a data source for your MSTest tests to set up the connection and then do whatever else it is you need to do.