How to test a function that has side effects? - testing

Given a function that does some operation on a database for instance.
In python, it would look like the following:
def dao_transfer(cnx, account_id1, account_id2, money):
spam = cnx.execute('query 1', account_id1)
egg = cnx.execute('query 2', account_2, spam)
return egg
What I do in my unit tests is that I mock the cnx object, and only check
that cnx.execute is called and that dao_transfer returns the last mock return value of cnx.execute.
I have the feeling that this poor testing.
What Django does, is that it doesn't unittest functions that interacts with the database but instead, do what I call integration tests ie. you spawn a full database, you load it with some initial data, execute your side-effect powered function and check that the database is in the correct state.
I could do that, but I'd rather prefer unittests. Is there an approach to unit testing side effect function that doesn't rely on checking every single side effect function calls arguments?
Is there pure approach to IO that allows better unit testing?

Related

Seed random number for unit tests in golang

I have functions that uses math/rand to "randomly" sample from a Poisson and another from the binomial distribution. It is often used by other functions that also return random values like h(g(f())) where f() g() and h() are random functions.
I placed a rand.Seed(n) call in main() to pick a different seed every time the program is run and it works fine.
My question is for unittests for these PRNG functions and the functions that use them using the builtin testing package. I would like to remove the randomness so that I can have a predictable value to compare with.
Where is the best place to place my constant value seed to get deterministic output? At the init() of the test file or inside every test function, or somewhere else?
You should certainly not put it in the test init() function. Why? Because execution order (or even if test functions are run) is non-deterministic. For details, see How to run golang tests sequentially?
What does this mean?
If you have 2 test functions (e.g. TestA() and TestB()) both of which test functions that call into math/rand, you don't have guarantees if TestA() is run first or TestB(), or even if any of those will be called. And so random data returned by math/rand will depend on this order.
A better option would be to put seeding into TestA() and TestB(), but this may also be insufficient, as tests may run parallel, so the random data returned by math/rand may also be non-deterministic.
To really have deterministic test results, functions that need random data would need to receive a math.Rand value and use that explicitly, and in tests you can create separate, distinct math.Rand values that will not be used by other tests, so seeding those to constant values and using those in the tested functions, only then can you have deterministic results that will not depend on how and in which order the test functions are called.
As an alternative to passing in a math.Rand you could monkey patch IF you you don't want dependency injection to be part of your package's API e.g.: https://play.golang.org/p/cIGxhO0wSbo
To stay compatible with parallel test execution, create your own rand.Rand.
My example includes Check() from the standard package testing/quick which is often used to execute tests on a hundred of pseudo-random arguments. (Similarly to OP's case, it's a function that makes your tests very much dependent on RNG seeding).
package main
import (
"math/rand"
"testing"
"testing/quick"
)
func TestRandomly(t *testing.T) {
r := rand.New(rand.NewSource(0))
config := &quick.Config{Rand: r}
assertion := func(num uint8) bool {
// fail test when argument is 254
return num != 254
}
if err := quick.Check(assertion, config); err != nil {
t.Error("failed checks", err)
}
}

How should I deal with external dependencies in my functions when writing unit tests?

The following function iterates through the names of directories in the file system, and if they are not in there already, adds these names as records to a database table. (Please note this question applies to most languages).
def find_new_dirs():
dirs_listed_in_db = get_dirs_in_db()
new_dirs = []
for dir in get_directories_in_our_path():
if dir not in dirs_listed_in_db:
new_dirs.append(dir)
return new_dirs
I want to write a unit test for this function. However, the function has a dependency on an external component - a database. So how should I write this test?
I assume I should 'mock out' the database. Does this mean I should take the function get_dirs_in_db as a parameter, like so?
def find_new_dirs(get_dirs_in_db):
dirs_listed_in_db = get_dirs_in_db()
new_dirs = []
for dir in get_directories_in_our_path():
if dir not in dirs_listed_in_db:
new_dirs.append(dir)
return new_dirs
Or possibly like so?
def find_new_dirs(db):
dirs_listed_in_db = db.get_dirs()
new_dirs = []
for dir in get_directories_in_our_path():
if dir not in dirs_listed_in_db:
new_dirs.append(dir)
return new_dirs
Or should I take a different approach?
Also, should I design my whole project this way from the start? Or should I refactor them to this design when the need arises when writing tests?
What you're describing is called dependency injection and yes, it is a common way of writing testable code. The second method you outlined (where you would pass in the db) is probably more common. Also, you can have the db parameter to your function take a default value so you are able to only specify the mock db in testing cases.
Whether to write your code that way at the outset or modify it later would be a matter of opinion, but if you adhere to the Test-driven development (TDD) methodology then you would write your tests before your code-under-test anyway.
There are other ways to deal with this problem, but you're asking a broad question at that point.
I take it these code fragments are python, which I'm not familiar with, but in any case this looks like the methods are detached from any stateful object and I'm not sure if that's idiomatic python or simply your design.
In an OOD you'd want an object that holds a data access object in its state (similar to your 2nd version) and mock that object for tests. You'd also want to mock the get_directories_our_path part.
As for when this design should be done - as the first step before creating the first code file. You should use dependency injection throughout your code. This will aid in testing as well as decoupling and increased reusability of your classes.

Execute command block in primitive in NetLogo extension

I'm writing a primitive that takes in two agentsets and a command block. It needs to call a few functions, execute the command block in the current context, and then call another function. Here's what I have so far:
class WithContext(pushGraphContext: GraphContext => Unit, popGraphContext: api.World => GraphContext)
extends api.DefaultCommand {
override def getSyntax = commandSyntax(
Array(AgentsetType, AgentsetType, CommandBlockType))
def perform(args: Array[Argument], context: Context) {
val turtleSet = args(0).getAgentSet.requireTurtleSet
val linkSet = args(1).getAgentSet.requireLinkSet
val world = linkSet.world
val gc = new GraphContext(world, turtleSet, linkSet)
val extContext = context.asInstanceOf[ExtensionContext]
val nvmContext = extContext.nvmContext
pushGraphContext(gc)
// execute command block here
popGraphContext(world)
}
}
I looked at some examples that used nvmContext.runExclusively, but that looked like it's specifically for having a given agentset run the command block. I want the current agent (possibly the observer) to run it. Should I wrap nvm.agent in an agentset and pass that to nvmContext.runExclusively? If so, what's the easiest way to wrap an agent in agentset? If not, what should I do?
Method #1
The quicker-but-arguably-dirtier method is to use runExclusiveJob, as demonstrated in (e.g.) the create-red-turtles command in https://github.com/NetLogo/Sample-Scala-Extension/blob/master/src/SampleScalaExtension.scala .
To wrap the current agent in an agentset, you can use agent.AgentSetBuilder. (You could also pass an Array[Agent] of length 1 to one of the ArrayAgentSet constructors, but I'd recommend AgentSetBuilder since it's less reliant on internal implementation details which are likely to change.)
Method #2
The disadvantage of method #1 is the slight constant overhead associated with creating and setting up the extra AgentSet, Job, and Context objects and directing execution through them.
Creating and running a separate job isn't actually how built-in commands like if and while work. Instead of making a new job, they remain in the current job and cause commands in a command block to run (or not run) by manipulating the instruction pointer (nvm.Context.ip) to jump into them or skip over them.
I believe an extension command could do the same. I'm not certain if it has been tried before, but I can't see any reason it wouldn't work.
Doing it this way would involve understanding more about NetLogo engine internals, as documented at https://github.com/NetLogo/NetLogo/wiki/Engine-architecture . You'd model your primitive after e.g. https://github.com/NetLogo/NetLogo/blob/5.0.x/src/main/org/nlogo/prim/etc/_if.java , including altering your implementation of nvm.CustomAssembled. (Note that prim._extern, which runs extension commands, delegates its assemble method to the wrapped command's own assemble method, so this should work.) In your assemble method, instead of calling done() at the end to terminate the job, you'd just allow execution to fall through.
I could try to construct an example that works this way, but it'd take me a couple hours; it's probably not worth me doing unless there's a real need.

Unit Testing in Visual Studio

I'm wanting to create a load of unit tests to make sure my stored procedures are working, but i'm failing (i'm new to tests in visual studio).
Basically I want to do the following:
<testclass()>
Dim myglobalvariable as integer
<testmethod()>
Public sub test()
-> use stored procedure to insert a record
set myglobalvariable = result from the sp
end sub
public sub test2()
-> use a stored procedure to modify the record we just added
end sub
public sub test3()
-> use a stored procedure to delete the record we just added
end sub
end class
The problem is because the tests don't run sequentially, tests 2 and 3 fail because the global variable isn't set.
Advise? :'(
The key word here is 'unit'.
A unit test should be self-contained, i.e. be comprised of the code to perform the test, and should not rely on other tests being executed first, or affect the operation of other tests.
See the list of TDD anti-patterns here for things that you should avoid when writing tests.
http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/
Check out the TestInitializeAttribute. You would place this on a method that should run before every test to allocate the appropriate resources.
One side note since it looks like you're misinterpreting how these should work: Unit tests should not require artifacts from other tests. If you're testing modifications, the initialize / setup method(s) should create the space that's to be modified.
Check out Why TestInitialize gets fired for every test in my Visual Studio unit tests?
I think that will point you in the correct direction. Instead of running it as a test, you could run it as a TestInitialize.
There are 'Ordered tests' but it breaks the idea of each test running independent.
First off, the test you describe doesn't sound like a unit test, but more like an integration test. A unit test is typically testing a unit of functionality in your code, isolated from the rest of the system, and runs in memory. An integration test aims at verifying that the components of the system, when assembled together, work as intended.
Then, without going into the details of the system, it looks to me that I would approach it as one single test, calling multiple methods - something along the lines of:
[Test]
public void Verify_CreateUpdateDelete()
{
CreateEntity();
Assert that the entity exists
UpdateEntity();
Assert that the entity has been updated
DeleteEntity();
Assert that the entity has been deleted
}

RFC for remote call transaction

How do I call the SAP report (for example RSPARAM) with help JCo?
What RFC may be used to remotely call SA38 transaction with RSPARAM (e.t.c.) as parameter and then return results for later work ?
RFC is for calling function modules, not programs. It's possible to use some generic function module to start a report, but since you'll usually want to process the results of the program and the program does not know that it was meant to deliver its results in a machine-readable way, you probably won't get too far this was. What exactly are you trying to do?
With the nearly infinite possible results of calling a transaction, i don't think there is a RFC to execute such an operation and return a result. What would be the result in case of an ALV display, or if the program then wait for some interactions ?
You can display a transaction in SAP portal using transactions Iviews. You're then using the portal page as a HTMLGui for your transaction.
also, some FM can sometime be used to perform operations instead of a full program (ie HR_INFOTYPE_OPERATION instead of pa30).
regards
Guillaume
Edition : since you want the result of RRSPARAM, you could encapsulate the "important" part (form SHOW_ACTUAL_PAR_VALUES_ALV) in a module function accessible by RFC, and returning a table of CST_RSPFPAR_ALV (ie the same structure that is displayed in the report)
regards
If You don't find a function to call, just create one by yourself. Tag it as callable from outside via RFC and in the coding, perform such things as "submit report xyz with param1 = value1 ... and return ... exporting list to memory". Then you can even return list output from this. Define the interface of the freshly created function module as you need (that means, report name as input, list output as a table of strings, e.g.). Attention, there is of course a big security risk, having an remote function accepting variable reportnames. But I am sure You know :-)