mardi 28 juin 2016

Objective-C XCTAssertEqualObjects unit test fails even though objects are identical

I'm developing an artificial neural net in objective c, so I've written some methods for matrix-vector arithmetic. For example, below is the code for the outer product calculation. The code is working fine and returns the desired results, but my unit test fails when comparing the method-returned NSMutableArray object to the one created in the unit test. I've been lost on this for a few days now. Does anyone know why XCTAssertEqualObjects fails despite the fact that the objects seem identical?

Here is the relevant code to return the outer product of 2 vectors (NSArrays) in MLNNeuralNet.m:

-(NSMutableArray *)outerProduct:(NSArray *)matrix1 by:(NSArray *)matrix2 {

/*Tensor Product of 2 vectors treated as column and row matrices, respectively*/

/*Example: if matrix1 is @[2, 4, 6] and matrix2 @[3, 4, 5], then calculation is:
 [2 * 3, 2 * 4, 2 * 5], [4 * 3, etc...]
 and result is:
 @[@[6, 8, 10], @[12, 16, 20], @[18, 24, 30]]
 */

NSMutableArray *result = [[NSMutableArray alloc] init];

for (int i = 0; i < [matrix1 count]; i++) {
    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    for (int j = 0; j < [matrix2 count]; j++) {
        double product = [[matrix1 objectAtIndex:i] doubleValue] * [[matrix2 objectAtIndex:j] doubleValue];
        [tempArray addObject:@(product)];
    }
    [result addObject:tempArray];
}

return result;
}

And here is the code for the unit test:

@interface MLNNeuralNetTests : XCTestCase

@property (strong, nonatomic) MLNNeuralNet *neuralNet;

@end

@implementation MLNNeuralNetTests

- (void)setUp {
    [super setUp];
    _neuralNet = [[MLNNeuralNet alloc] init];
}

-(void)testOuterProduct {

NSMutableArray *matrix1 = [[NSMutableArray alloc] initWithArray:@[@(1.0), @(2.0), @(3.0)]];
NSMutableArray *matrix2 = [[NSMutableArray alloc] initWithArray:@[@(4.2), @(5.2), @(6.2)]];

NSMutableArray *layer1 = [[NSMutableArray alloc] initWithArray:@[@(4.2), @(5.2), @(6.2)]];
NSMutableArray *layer2 = [[NSMutableArray alloc] initWithArray:@[@(8.4), @(10.4), @(12.4)]];
NSMutableArray *layer3 = [[NSMutableArray alloc] initWithArray:@[@(12.6), @(15.6), @(18.6)]];
NSMutableArray *correctMatrix = [[NSMutableArray alloc]
                                 initWithArray:@[layer1, layer2, layer3]];

NSMutableArray *testMatrix = [self.neuralNet outerProduct:matrix1 by:matrix2];

XCTAssertEqualObjects(correctMatrix, testMatrix, @"Matrix outer product failed");
}

And here is the error I'm getting:

I thought it might be due to my creating the NSNumber literals in the unit test version like @(4.2) etc...

so I tried first creating doubles and then wrapping in NSNumber like this:

double number1 = 4.2;
NSMutableArray *layer1 = [[NSMutableArray alloc] initWithArray:@[@(number1), etc...

but this also did not work.

Am I missing something here?

Maven FailSafe Plugin runs both integration and unit tests

I'm using the Surefire plugin and Failsafe plugin for unit tests and integration tests, respectively. But when I run mvn integration-test it runs both unit and integration tests, and when I run mvn failsafe:integration-test no tests are run.

My pom.xml for the plugins looks as follows

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <excludedGroups>my.project.inittest.IntegrationTest</excludedGroups>
    </configuration>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            <configuration>
                <includes>
                    <include>**/*.class</include>
                </includes>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <groups>my.project.inittest.IntegrationTest</groups>
    </configuration>
</plugin>

And my tests are packaged as:

test
    java
        my.project
            inittest
                IntegrationTest1.java
            service
                ServiceUnitTest1.java
            UnitTest1.java

How do I get it to run only integration tests?

PHPUnit mocking object that is the same type as the SUT and is a property of the SUT

I have a class called TestClass which has a property called parent. The parent property is the same type as the TestClass. Show below is a portion of the TestClass I am trying to test.

class TestClass
{
    /**
     * @param array $parentIds
     * @return ApiLock[]
     */
    protected function getParentLocks(array $parentIds)
    {
        if ($this->getParent()) {
            $id = array_pop($parentIds);
            return $this->getParent()->getLocks($id, $parentIds);
        }

        return [];
    }

    /**
     * @param array $ids
     * @return ApiLock[]
     */
    protected function getLocks($id, array $ids)
    {
        $locks = $this->getParentLocks($ids);

        if ($this->config->getLockName()) {
            $locks[] = new ApiLock($this->config->getLockName() . '.' . $id, $this->config->getLockWait());
        }

        return $locks;
    }

}

The method getLocks calls the getParentLocks method. To test this class, I have mocked TestClass object and set as the parent of the SUT. Something similar to this.

$apiLock = $this->getMockBuilder(ApiLock::class)
            ->disableOriginalConstructor()
            ->getMock();
        $parent = $this->getMockBuilder(TestClass::class)
            ->disableOriginalConstructor()
            ->getMock();

        $parent->expects($this->any())
            ->method('getLocks')
            ->will($this->returnValue([$apiLock]));

        $testClass->setParent($parent);

But when i run the tests , the method setLocks on the parent object will not return the stubbed value but will actually call the setLocks method on the parent object and the test fails. May be I am not seeing something obvious. The stubbed method should be called instead of the real method on the parent object. Please help me thanks in advance.

Unittest __unittest_skip__ access in beforeTest method

I am using the skip decorator for a test:

@skip('I want this to skip')
def test_abc(self):

I also have a nose plugin to report test results with a defined

def beforeTest(self, *args, **kwargs):

the test case test_abc is getting captured by the beforeTest method. How can I check for the decorator value in my beforeTest method?

I see that the definition of unittest decorator has the following code:

test_item.__unittest_skip__ = True
test_item.__unittest_skip_why__ = reason

But I dont know how to access it from beforeTest. When running args[0].test has the test case object but I can seem to find where __unittest_skip__ is defined

Thanks!

Tornado Unittest mock yield statements

When running Unit tests for a tornado application i keep getting this error:

tornado.ioloop.TimeoutError: Operation timed out after 5 seconds

here's the test code:

class TestMongo(testing.AsyncTestCase):

def setUp(self):
    super().setUp()
@patch('stashboard.checkers.events')
@testing.gen_test()
def test_check(self, event_mock,): # tests for Ok connection status
    event_mock.STATUS_OK = events.STATUS_OK
    event_mock.STATUS_FAIL = events.STATUS_FAIL
    event_mock.save.return_value = Future()
    d = {'path': '/test'}
    test = MongoChecker(d, 1, None)
    yield test.check()
    event_mock.save.assert_called_with({'path': '/test'},
                                 {'status': events.STATUS_OK,
                             'address': '#address#'})

and here's the code being tested:

class MongoChecker(Checker):
# pings Mongo servers noted in configuration to make sure
# they are still running

def __init__(self, event, frequency, params):
    super().__init__(event, frequency, params)
    self.clients = []
    for server in configuration["mongodb"]:
        host = server["host"]
        port = server["port"]
        address = 'mongodb://{}:{}'.format(host, port)
        client = motor.motor_tornado.MotorClient(
            address)
        # creates client to test connection
        client.address = address
        self.clients.append(client)

@gen.coroutine
def check(self):
    for client in self.clients:
        try:
            yield client.admin.command('ping')
            data= {'address': client.address, 'status': events.STATUS_OK}
        except ConnectionError:
            data = {'address': client.address, 'status': events.STATUS_FAIL}
        yield self.save(data)

This is the method that is actually called for the assertion:

@gen.coroutine
def save(self, data):
    yield events.save(self.event, data)

When I remove the yield statement from yield self.save(data) the test works fine. I need to mock a Future object to return from self.save and also get the actual results from that.

Unit testing a custom command

I've been able to test the behaviour of a custom command that I added.

However, I would like to be able to unit test it. All the logic that I have is in the handle method. I am injecting a class into the constructor of my custom command class. Now I would like to be able to mock it and use several scenarios with the mock.

Here is an example that illustrates How the custom class looks like:

class CustomCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'custom:generate 
                            {--myoption= : The option to generate }';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generates ...';

    /**
     * SqlMigrator class
     *
     * @customGenerator App\Scripts\CustomGenerator
     */
    private $customGenerator;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(CustomGenerator $cg)
    {
        parent::__construct();
        $this->customGenerator = $cg;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $myoption = $this->option('myoption');
        switch($myoption){
            case "case1": 
                            $this->cg->processCase1();
                            .
                            .
                            break;
            case "case2": 
                            .
                            .
                            .
                            break;
        }

Basically by mocking CustomGenerator class , and also setting the options of the custom class (myoption in this example) I will be able to unit test all the senarios.

All suggestions are welcome.

Thanks

Unit test function that enforces specific decimal precision level

I'm writing software for counting preferential multi-seat elections. One common requirement is fixed precision. This means that all math operations must be done on values with a fixed specified precision and the result must have the same precision. Fixed precision means a set number of digits after the decimal. Any digits after that are discarded.

So if we assume 5 digits of precision:

    42/139

becomes:

    42.00000/139.00000 = 0.30215

I'm having problems writing unit tests for this. So far I've written these two tests for big and small numbers.

    public void TestPrecisionBig()
    {
        PRECISION = 5;
        decimal d = Precision(1987.7845263487169386183643876m);
        Assert.That(d == 1987.78452m);
    }

    public void TestPrecisionSmall()
    {
        PRECISION = 5;
        decimal d = Precision(42);
        Assert.That(d == 42.00000m);
    }

But it evaluates to 42 == 42.00000m Not what I want.

How do I test this? I guess I could do a d.ToString, but would that be a good "proper" test?