Is it a good idea to inject a TestSettings parameter to a method to make it (Unit or integration) Testable? - oop

Is it a good practice to introduce a TestSettings class in order to provide flexible testing possibilities of a method that has many processes inside?
Maybe not a good example but can be simple: Suppose that I have this method and I want to test its sub-processes:
public void TheBigMethod(myMethodParameters parameter)
{
if(parameter.Condition1)
{
MethodForCondition1("BigMac");
}
if(parameter.Condition2)
{
MethodForCondition2("MilkShake");
}
if(parameter.Condition3)
{
MethodForCondition3("Coke");
}
SomeCommonMethod1('A');
SomeCommonMethod2('B');
SomeCommonMethod3('C');
}
And imagine that I have unit tests for all
void MethodForCondition1 (string s)
void MethodForCondition2 (string s)
void MethodForCondition3 (string s)
void SomeCommonMethod1 (char c)
void SomeCommonMethod2 (char c)
void SomeCommonMethod3 (char c)
And now i want to test the TheBigMethod itself by introducing such test methods with required Asserts in them:
TheBigMethod_MethodForCondition1_TestCaseX_DoesGood
TheBigMethod_MethodForCondition2_TestCaseY_DoesGood
TheBigMethod_MethodForCondition3_TestCaseZ_DoesGood
TheBigMethod_SomeCommonMethod1_TestCaseU_DoesGood
TheBigMethod_SomeCommonMethod2_TestCaseP_DoesGood
TheBigMethod_SomeCommonMethod3_TestCaseQ_DoesGood
So, I want TheBigMethod to be exit-able at some points if it is called by one of my integration tests above.
public void TheBigMethod(myMethodParameters parameter, TestSettings setting)
{
if(parameter.Condition1)
{
MethodForCondition1("BigMac");
if(setting.ExitAfter_MethodForCondition1)
return;
}
if(parameter.Condition2)
{
MethodForCondition2("MilkShake");
if(setting.ExitAfter_MethodForCondition2)
return;
}
if(parameter.Condition3)
{
MethodForCondition3("Coke");
if(setting.ExitAfter_MethodForCondition3)
return;
}
SomeCommonMethod1('A');
if(setting.ExitAfter_SomeCommonMethod1)
return;
SomeCommonMethod2('B');
if(setting.ExitAfter_SomeCommonMethod2)
return;
SomeCommonMethod3('C');
if(setting.ExitAfter_SomeCommonMethod3)
return;
}
Even though it looks it does what I need to introduce a TestSetting parameter can makee the code less readable and does not look nice to have testing logic and the main functionality combined to me.
Can you advise a better design for such cases so that it can replace a TestSetting parameter idea?
thanks

It would (IMO) be a very bad thing to add this TestSetting. An alternative would be to add an interface (or set of interfaces) for MethodForConditionX and SomeCommonMethodX. The test each of the MethodForConditionX & SomeCommonMethodX in isolation and pass in a stub for TheBigMethod which validates that MethodForConditionX is called with value Z.
Edit: You could also make the methods virtual if you don't want to use an interface.

A bit late to the game here, but I would concur that mixing test and production code is a big code smell to be avoided. Big methods in legacy code provide all sorts of issues. I would highly recommend reading Michael Feather's Working Effectively with Legacy Code. It's all about dealing with the myriad of problems encountered in legacy code and how to deal with them.

Related

Programmatically execute Gatling tests

I want to use something like Cucumber JVM to drive performance tests written for Gatling.
Ideally the Cucumber features would somehow build a scenario dynamically - probably reusing predefined chain objects similar to the method described in the "Advanced Tutorial", e.g.
val scn = scenario("Scenario Name").exec(Search.search("foo"), Browse.browse, Edit.edit("foo", "bar")
I've looked at how the Maven plugin executes the scripts, and I've also seen mention of using an App trait but I can't find any documentation for the later and it strikes me that somebody else will have wanted to do this before...
Can anybody point (a Gatling noob) in the direction of some documentation or example code of how to achieve this?
EDIT 20150515
So to explain a little more:
I have created a trait which is intended to build up a sequence of, I think, ChainBuilders that are triggered by Cucumber steps:
trait GatlingDsl extends ScalaDsl with EN {
private val gatlingActions = new ArrayBuffer[GatlingBehaviour]
def withGatling(action: GatlingBehaviour): Unit = {
gatlingActions += action
}
}
A GatlingBehaviour would look something like:
object Google {
class Home extends GatlingBehaviour {
def execute: ChainBuilder =
exec(http("Google Home")
.get("/")
)
}
class Search extends GatlingBehaviour {...}
class FindResult extends GatlingBehaviour {...}
}
And inside the StepDef class:
class GoogleStepDefinitions extends GatlingDsl {
Given( """^the Google search page is displayed$""") { () =>
println("Loading www.google.com")
withGatling(Home())
}
When( """^I search for the term "(.*)"$""") { (searchTerm: String) =>
println("Searching for '" + searchTerm + "'...")
withGatling(Search(searchTerm))
}
Then( """^"(.*)" appears in the search results$""") { (expectedResult: String) =>
println("Found " + expectedResult)
withGatling(FindResult(expectedResult))
}
}
The idea being that I can then execute the whole sequence of actions via something like:
val scn = Scenario(cucumberScenario).exec(gatlingActions)
setup(scn.inject(atOnceUsers(1)).protocols(httpConf))
and then check the reports or catch an exception if the test fails, e.g. response time too long.
It seems that no matter how I use the 'exec' method it tries to instantly execute it there and then, not waiting for the scenario.
Also I don't know if this is the best approach to take, we'd like to build some reusable blocks for our Gatling tests that can be constructed via Cucumber's Given/When/Then style. Is there a better or already existing approach?
Sadly, it's not currently feasible to have Gatling directly start a Simulation instance.
Not that's it's not technically feasible, but you're just the first person to try to do this.
Currently, Gatling is usually in charge of compiling and can only be passed the name of the class to load, not an instance itself.
You can maybe start by forking io.gatling.app.Gatling and io.gatling.core.runner.Runner, and then provide a PR to support this new behavior. The former is the main entry point, and the latter the one can instanciate and run the simulation.
I recently ran into a similar situation, and did not want to fork gatling. And while this solved my immediate problem, it only partially solves what you are trying to do, but hopefully someone else will find this useful.
There is an alternative. Gatling is written in Java and Scala so you can call Gatling.main directly and pass it the arguments you need to run the Gatling Simulation you want. The problem is, the main explicitly calls System.exit so you have to also use a custom security manager to prevent it from actually exiting.
You need to know two things:
the class (with the full package) of the Simulation you want to run
example: com.package.your.Simulation1
the path where the binaries are compiled.
The code to run a Simulation:
protected void fire(String gatlingGun, String binaries){
SecurityManager sm = System.getSecurityManager();
System.setSecurityManager(new GatlingSecurityManager());
String[] args = {"--simulation", gatlingGun,
"--results-folder", "gatling-results",
"--binaries-folder", binaries};
try {
io.gatling.app.Gatling.main(args);
}catch(SecurityException se){
LOG.debug("gatling test finished.");
}
System.setSecurityManager(sm);
}
The simple security manager i used:
public class GatlingSecurityManager extends SecurityManager {
#Override
public void checkExit(int status){
throw new SecurityException("Tried to exit.");
}
#Override
public void checkPermission(Permission perm) {
return;
}
}
The problem is then getting the information you want out of the simulation after it has been run.

Dealing with code duplication in tests

At work I practice Test Driven Development as much as possible. One thing I often end up in though is having to set up a bunch of DTO's and when these have a slightly complex structure this becomes quite alot of code. The problem with this is that the code is often quite repettetive and I feel it distracts from the main purpose of the test. For instance using a slightly contrieved and condensed example (in java, jUnit + mockito):
class BookingServiceTest {
private final static int HOUR_IN_MILLIS = 60 * 60 * 1000;
private final static int LOCATION_ID = 1;
#Mock
private BookingLocationDao bookingLocationDao;
#InjectMocks
private BookingService service = new BookingService();
#Test
public void yieldsAWarningWhenABookingOverlapsAnotherInTheSameLocation() {
// This part is a bit repetetive over many tests:
Date now = new Date()
Location location = new Location()
location.setId(LOCATION_ID);
Booking existingBooking = new Booking()
existingBooking.setStart(now);
existingBooking.setDuration(HOUR_IN_MILLIS);
existingBooking.setLocation(location);
// To here
when(bookingLocationDao.findBookingsAtLocation(LOCATION_ID))
.thenReturn(Arrays.asList(existingBooking));
// Then again setting up a booking :\
Booking newBooking = new Booking();
newBooking.setStart(now);
newBooking.setDuration(HOUR_IN_MILLIS / 2);
newBooking.setLocation(location);
// Actual test...
BookingResult result = service.book(newBooking);
assertThat(result.getWarnings(), hasSize(1));
assertThat(result.getWarnings().get(0).getType(), is(BookingWarningType.OVERLAPING_BOOKING));
}
}
In this example the setup is not that complicated so I wouldn't think of it too much. However, when more complicated input is required the code for the setup of the input to methods tend to grow. The problem gets exacerbated by similar input being used in several tests. Refactoring the setup code into a separate TestUtil class helps a bit. The problem then is that it is a bit hard to find these utility classes when writing new tests a couple of month's later, which then leads to duplication.
What is a good way of dealing with this kind of "complex" DTOs in order to minimize code duplication in test setups?
How do you ensure that extracted TestUtilities are found when working with similar code?
Am I doing it wrong? :) Should I build my software in another way as to avoid this situation altogether? If so, how?
There are a couple of patterns which are of interest for handling this type of situation:
Object Mother
Test Data Builder
For an in-depth discussion about these patterns, take a look at the excellent book "Growing Object-oriented Software Guided by Tests"
Test Data Builder
A builder class is created for each class for which you want to facilitate instantiation/setup. This class contains a bunch of methods which set up the object being built in specific states. Usually these helper methods return an instance to the builder class, so that the calls can be chained in a fluent style.
// Example of a builder class:
public class InvoiceBuilder {
Recipient recipient = new RecipientBuilder().build();
InvoiceLines lines = new InvoiceLines(new InvoiceLineBuilder().build());
PoundsShillingsPence discount = PoundsShillingsPence.ZERO;
public InvoiceBuilder withRecipient(Recipient recipient) {
this.recipient = recipient;
return this;
}
public InvoiceBuilder withInvoiceLines(InvoiceLines lines) {
this.lines = lines;
return this;
}
public InvoiceBuilder withDiscount(PoundsShillingsPence discount) {
this.discount = discount;
return this;
}
public Invoice build() {
return new Invoice(recipient, lines, discount);
}
}
// Usage:
Invoice invoiceWithNoPostcode = new InvoiceBuilder()
.withRecipient(new RecipientBuilder()
.withAddress(new AddressBuilder()
.withNoPostcode()
.build())
.build())
.build();
Object Mother
An object mother is a class that provides pre-made test data for different common scenarios.
Invoice invoice = TestInvoices.newDeerstalkerAndCapeInvoice();
The examples above are borrowed from Nat Pryce's blog.
As Erik rightly points out the frequently used patterns to solve this are TestDataBuilder and ObjectMother. These are also covered in depth in: Mark Seemans advanced unit testing course as well as growing object oriented software guided by tests, both are very good.
In practice I find that the Test Data Builder pattern almost always leads to better, more readable tests than the ObjectMother pattern except in the simplest cases (as you often need a surprising number of overloads for the objectmother pattern).
Another trick that you can use is to bunch together sets of setups with the test object builder pattern into single methods e.g.
Invoice invoiceWithNoPostcode = new InvoiceBuilder()
.withRecipient(new RecipientBuilder()
.withAddress(new AddressBuilder()
.withNoPostcode()
.build())
.build())
.build();
Could become:
new InvoiceBuilder().WithNoPostCode().Build();
And in some cases that can lead to even simpler test setups, but doesn't work in all cases.

Object oriented design patterns for parsing text files?

As part of a software package I'm working on, I need to implement a parser for application specific text files. I've already specified the grammar for these file on paper, but am having a hard time translating it into easily readable/updatable code (right now just it passes each line through a huge number of switch statements).
So, are there any good design patterns for implementing a parser in a Java style OO environment?
Any easy way to break a massive switch into an OO design would be to have
pseudo code
class XTokenType {
public bool isToken(string data);
}
class TokenParse {
public void parseTokens(string data) {
for each step in data {
for each tokenType in tokenTypess {
if (tokenType.isToken(step)) {
parsedTokens[len] = new tokenType(step);
}
...
}
}
...
}
}
Here your breaking each switch statement into a method on that token object to detect whether the next bit of the string is of that token type.
Previously:
class TokenParse {
public void parseTokens(string data) {
for each step in data {
switch (step) {
case x:
...
case y:
...
...
}
}
...
}
}
One suggestion is to create property file where you define rules. Load it during run time and use if else loop (since switch statements also does the same internally). This way if you want to change some parsing rules you have to change .property file not code. :)
You need to learn how to express context free grammars. You should be thinking about the GoF Interpreter and parser/generators like Bison, ANTRL, lex/yacc, etc.

How do I sense if my unit test is a member of an ordered test and, if it is, which position in that ordered test it is at?

Environment:
I have a program - named CSIS - which I need to run a lot of automated tests on in Visual Studio 2010 using C#. I have a series of functions which need to be run in many different orders but which all start and end at the same 'home screen' of CSIS. The tests will either be run on their own as a single CodedUITest (.cs filetype) or as an ordered test (.orderedtest filetype).
Goal:
The goal is to open to the CSIS homepage once no matter which of the unit tests is run first and then, after all CodedUITests are finished, no matter which unit test is last, the automated test will close CSIS. I don't want to create a separate unit test to open CSIS to the homepage and another to close CSIS as this is very inconvenient for testers to use.
Current Solution Development:
UPDATE: The new big question is how do I get '[ClassInitialize]' to work?
Additional Thoughts:
UPDATE: I now just need ClassInitialize to execute code at the beginning and ClassCleanUp to execute code at the end of a test set.
If you would like the actual code let me know.
Research Update:
Because of Izcd's answer I was able to more accurately research the answer to my own question. I've found an answer online to my problem.
Unfortunately, I don't understand how to implement it in my code. I pasted the code as shown below in the 'Code' section of this question and the test runs fine except that it executes the OpenWindow() and CloseWindow() functions after each test instead of around the whole test set. So ultimately the code does nothing new. How do I fix this?
static private UIMap sharedTest = new UIMap();
[ClassInitialize]
static public void ClassInit(TestContext context)
{
Playback.Initialize();
try
{
sharedTest.OpenCustomerKeeper();
}
finally
{
Playback.Cleanup();
}
}
=====================================================================================
Code
namespace CSIS_TEST
{
//a ton of 'using' statements are here
public partial class UIMap
{
#region Class Initializization and Cleanup
static private UIMap sharedTest = new UIMap();
[ClassInitialize]
static public void ClassInit(TestContext context)
{
Playback.Initialize();
try
{
sharedTest.OpenWindow();
}
finally
{
Playback.Cleanup();
}
}
[ClassCleanup]
static public void ClassCleanup()
{
Playback.Initialize();
try
{
sharedTest.CloseWindow();
}
finally
{
Playback.Cleanup();
}
}
#endregion
Microsoft's unit testing framework includes ClassInitialise and ClassCleanUp attributes which can be used to indicate methods that execute functionality before and after a test run.
( http://msdn.microsoft.com/en-us/library/ms182517.aspx )
Rather than try and make the unit tests aware of their position, I would suggest it might be better to embed the opening and closing logic of the home screen within the aforementioned ClassInitialise and ClassCleanUp marked methods.
I figured out the answer after a very long process of asking questions on StackOverflow, Googling, and just screwing around with the code.
The answer is to use AssemblyInitialize and AssemblyCleanup and to write the code for them inside the DatabaseSetup.cs file which should be auto-generated in your project. You should find that there already is a AssemblyInitialize function in here but it is very basic and there is no AssemblyCleanup after it. All you need to do is create a static copy of your UIMap and use it inside the AssemblyInitialize to run your OpenWindow() code.
Copy the format of the AssemblyInitialize function to create an AssemblyCleanup function and add your CloseWindow() function.
Make sure your Open/CloseWindow functions only contains basic code (such as Process.Start/Kill) as any complex variables such as forms have been cleaned up already and won't work.
Here is the code in my DatabaseSetup.cs:
using System.Data;
using System.Data.Common;
using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Data.Schema.UnitTesting;
using System.Windows.Input;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using Mouse = Microsoft.VisualStudio.TestTools.UITesting.Mouse;
using MouseButtons = System.Windows.Forms.MouseButtons;
namespace CSIS_TEST
{
[TestClass()]
public class DatabaseSetup
{
static private UIMap uIMap = new UIMap();
static int count = 0;
[AssemblyInitialize()]
public static void InitializeAssembly(TestContext ctx)
{
DatabaseTestClass.TestService.DeployDatabaseProject();
DatabaseTestClass.TestService.GenerateData();
if(count < 1)
uIMap.OpenWindow();
count++;
}
[AssemblyCleanup()]
public static void InitializeAssembly()
{
uIMap.CloseWindow();
}
}
}

AspectJ - Why put transaction control in a seperate place?

Ok, I haven't fully understood the philosophy why AOP AspectJ is good for. I have now implemented a Logging and transaction control for when withdrawing money from a bankaccount. Alright, why is it good in doing that? I could likewise implement the control in the same class file where I've also stored all my banking methods (withdraw, deposit, balance... etc). And the logging I could've create a new class for it, and thereafter make an instance of it in the BankAccount class.
So why do I need to use AOP, AspectJ for it? I haven't fully understood the idea...
Here's my aspect file
public aspect SafeWithdrawal {
pointcut checking(BankAccount bk, float x): execution(* BankAccount.withdraw(float)) && target(bk) && args(x);
public static void BankAccount.LogChange(String str){
System.out.println(str);
}
before(BankAccount b, float x) : checking(b, x) {
if(b.getBalance() >= x) {
BankAccount.LogChange("Account changing. $" + x + " withdrawn...");
} else {
BankAccount.LogChange("Account does not have. $" + x + " to withdrawn...");
}
}
}
The idea is that your domain methods like withdraw can remain laser-focused on your business processes and secondary concerns like logging, transactions, profiling, etc. don't get in the way.