mardi 26 décembre 2017

Roboelectric slow and gives warnings

This is my first time using Roboelectric. Writing my first test which is just a simple test asserting the title of the Activity takes about 18s to execute and gives me the following warnings:

WARNING: no system properties value for "ro.control_privapp_permissions"
WARNING: no system properties value for "ro.crypto.state"
WARNING: no system properties value for "ro.crypto.type"

What are those warnings? and even if I ignore the warnings, should it really take 18s to execute this small test?

This is the test:

@Test
public void titleIsCorrect() throws Exception {
    Activity activity = Robolectric.setupActivity(MainActivity.class);
    assertTrue(activity.getTitle().toString().equals("Title"));
}

how to select drop-down options in cucumber rails

how to select drop-down options in cucumber rails browser.select(:xpath, '//[@id="login_form"]/div[2]/div[1]/div[4]/div/select').click browser.select(:xpath, '//[@id="login_form"]/div[2]/div[1]/div[4]/div/select/option[11]').click

Perl 6: automated testing of terminal-based programs

How could I automate interactions with command line programs that expose a text terminal interface with Perl 6 for testing purposes?

lundi 25 décembre 2017

Angular2/ionic2 testing: expected spy push to have been called

I am currently testing an ionic application. The problem is that the test fails, the error log is: "Expected spy push to have been called.". I really do not know why it does not work since I can get the element and I can click it. The console log does display that the size is. This means that it does contain that one button.

HTML :

<ion-header>
  <ion-navbar>
    <ion-title>Login</ion-title>
  </ion-navbar>
</ion-header>


<ion-content class="master">
    <div class="loginWindow">
      <ion-item>
        <ion-label fixed>Sign in</ion-label>
      </ion-item>
      <ion-item>
        <ion-label fixed>Email</ion-label>
        <ion-input type="email" name="email"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label fixed>Password</ion-label>
        <ion-input type="password" name="password"></ion-input>
      </ion-item>
      <ion-item>
        <div padding>
          <button ion-button (click)="doLogin()" id="loginButton" class="loginButtons" color="avioBlue" block>Sign in</button> <-- this is the button 
        </div>
      </ion-item>
    </div>
</ion-content>

And as for the test file:

it('should be able to navigate to home page', () => {

    let navCtrl = fixture.debugElement.injector.get(NavController);
    spyOn(navCtrl, 'push');

    const buttons = fixture.debugElement.queryAll(By.css("button"));
    console.log(buttons);
    de = buttons[0];
    de.triggerEventHandler('click', null);

    expect(navCtrl.push).toHaveBeenCalled();
  });

how to enable memory profiler only when testing in python?

I am using memory_profiler in python and profiling some piece of code. But I only want that to enable when testing is happening, like the function is being invoked from a test-suite. I don't want the profiler being enabled when code is running in production. Is there any way to do that?

Or I am open to generic suggestion like how to enable decorators only when the testing is happening.

Example code -

from memory_profiler import profile

@profile(precision=4)
def my_func():
    a = [1] * (10 ** 6)
    b = [2] * (2 * 10 ** 7)
    del b
    return a

test C program with some inputs

I wrote a program in c and I want to try it with some inputs. The inputs are not numbers so I cant use a for loop or something like this in the code. So I want to write a file with inputs and give it to the program so it will take every time (it waits to input) 1 line from the text file or something like this, is it possible?

Thank you in advance.

Node.js Mocha Sequelize Error ConnectionManager.getConnection was called after the connection manager was closed

There are 2 mocha test files:

  1. Creates a server and pings it using chai just to check if it's
    working
  2. Creates a server and tests user insertion into database (sequelize postgres)

Both of these servers initialize a database connection.

When ran independently both of them pass, when ran together the second one fails with the following error:

Error ConnectionManager.getConnection was called after the connection manager was closed

Looking at the console, connection with the database is established 2 times for each test, but still acts as a single pool.

# db/index.js

global.TABLE_USERS = 'users';

const Promise = require('bluebird');
const Sequelize = require('sequelize');
const config = require('./../config');
const User = require('./User');

/**
 * @return {Promise}
 */
const connect = () => {
    return new Promise((resolve, reject) => {
        let sequelize = new Sequelize(config.postgres.database, config.postgres.user, config.postgres.password, {
            host: config.postgres.host,
            dialect: 'postgres',
            pool: {
                max: 5,
                min: 0,
                acquire: 30000,
                idle: 10000
            },
            define: {
                underscored: false,
                freezeTableName: false,
                charset: 'utf8',
                dialectOptions: {
                    collate: 'utf8_general_ci'
                }
            },
        });

        let user = User(sequelize);

        sequelize
            .authenticate()
            .then(() => {
                resolve({
                    User: user,
                    sequelize: sequelize
                })
            })
            .catch(err => {
                console.error('Couldn\'t authenticate');
                reject(err)
            })
    });
};

module.exports.connect = connect;

Main server module:

const express = require('express');
const bodyParser = require('body-parser');
global.Promise = require('bluebird');
let routing = require('./routing');
const config = require('./config');
const middleware = require('./middleware');
let database = require('./db');
let Repositories = require('./repositories');
let Services = require('./services');
let Controllers = require('./controllers');
const Promise = require('bluebird');

/**
 * @property {http.Server} this.app
 */
class Server {

    constructor() {
        this.app = express();
    }

    /**
     * @param {Function} beforeHook
     *
     */
    init(beforeHook = null) {
        return this._initDatabaseConnection()
            .then(() => {
                this._initContainer(beforeHook);
                this._initRoutes();
                return this._initServer()
            });
    }

    /**
     *
     * @param {Function} beforeHook
     * @private
     */
    _initContainer(beforeHook) {
        this.container = {};
        // Modify for testing before starting
        if (typeof beforeHook === 'function') beforeHook(this);
        this.container = Repositories(this.database);
        this.container = Services(this.container);
        this.controllers = Controllers(this.container);
    }

    /**
     *
     * @private
     */
    _initRoutes() {
        this.app.use(bodyParser.json());
        middleware.handleCors(this.app);
        this.app.use(routing({...this.controllers, ...this.services}));
        middleware.handleErrors(this.app);
    }

    /**
     *
     * @private
     *
     * @return {Promise}
     */
    _initServer() {
        return new Promise((resolve, reject) => {
            this.server = this.app.listen(config.app.port, () => {
                console.log(`Server started listening in ${config.app.env} on port ${config.app.port}`);
                resolve(this)
            });
        });
    }

    /**
     *
     * @return {Promise}
     * @private
     */
    _initDatabaseConnection() {
        return database.connect()
            .then(connection => {
                this.database = connection;
                console.log('Connected to the database');

                return Promise.resolve()
            })
    }

    /**
     * @return {Promise}
     */
    close() {
        this.server.close();
        return this.database.sequelize.close();
    }
}

module.exports = Server;

First test case

const assert = require('assert');
const chai = require('chai'),
    expect = chai.expect,
    chaiHttp = require('chai-http');

chai.use(chaiHttp);

const Server = require('../../src/Server');

describe('Server app test', () => {

    let server;

    before(async () => {
        server = await (new Server()).init();
    });

    after(async () => {
        await server.close();
    });

    it('should say respond it\'s name', async () => {
        let pingServer = () => {
            return new Promise((resolve, reject) => {
                chai.request(server.server)
                    .get('/')
                    .end((err, res) => {
                        expect(err).to.be.null;
                        expect(res).to.have.status(200);
                        resolve(res.body)
                    });
            });
        };

        let res = await pingServer();
        assert.equal(res.msg, 'API server');
    });
});

Second test case, UserControllerTest

const assert = require('assert');
const chai = require('chai'),
    expect = chai.expect,
    chaiHttp = require('chai-http');

chai.use(chaiHttp);

const sinon = require('sinon');
const Promise = require('bluebird');
const Response = require('./../../src/lib/RequestHelper');
const UserValidation = require('./../../src/validation/UserValidation');
const Server = require('./../../src/Server');
const ReCaptchaService = require('./../../src/services/ReCaptchaService');
const ValidationError = require('./../../src/errors/ValidationError');


describe('/users/signup', () => {

    describe('valid reCaptcha scenario', () => {
        let server, reCaptchaServiceStub;

        before(async () => {
            reCaptchaServiceStub = sinon.stub(ReCaptchaService.prototype, 'authenticate').returns(true);

            function setReCaptchaServiceStub(server) {
                server.services = {ReCaptchaService: new reCaptchaServiceStub()};
            }

            server = await (new Server()).init(setReCaptchaServiceStub);
        });

        after(async () => {
            reCaptchaServiceStub.restore();
            await server.database.User.destroy({where: {}});
            await server.close();
        });

        beforeEach(async () => {
            await server.database.User.destroy({where: {}});
        });

        it('should allow user to register', async () => {

            let data = {email: 'myemail@gmail.com', password: '1234'};
            data[UserValidation.CAPTCHA_RESPONSE] = 'captcha_token';

            let signUp = (data) => {
                return new Promise((resolve, reject) => {
                    chai.request(server.server)
                        .post('/users/signup')
                        .send(data)
                        .end((err, res) => {
                            console.log(res.body)
                            expect(err).to.be.null;
                            expect(res).to.have.status(Response.STATUS_OK);
                            resolve(res.body)
                        });
                });
            };

            let res = await signUp(data);
            expect(res.token).to.be.a('string');
        });
    });

    describe('invalid reCaptcha scenario', () => {
        let server, reCaptchaServiceStub;

        before(async () => {
            reCaptchaServiceStub = sinon.stub(ReCaptchaService.prototype, 'authenticate')
                .onCall()
                .throws(new ValidationError('some err'));

            function setReCaptchaServiceStub(server) {
                server.container.ReCaptchaService = new reCaptchaServiceStub()
            }

            server = await (new Server()).init(setReCaptchaServiceStub);
        });

        after(async () => {
            reCaptchaServiceStub.restore();
            await server.close();
        });

        beforeEach(async () => {
            await server.database.User.destroy({where: {}});
        });

        it('should send a bad request on invalid reCaptcha', async () => {

            let data = {email: 'myemail@gmail.com', password: '1234'};
            data[UserValidation.CAPTCHA_RESPONSE] = 'random_token';

            let signUp = (data) => {
                return new Promise((resolve, reject) => {
                    chai.request(server.server)
                        .post('/users/signup')
                        .send(data)
                        .end((err, res) => {
                            expect(err).to.not.be.null;
                            expect(res).to.have.status(Response.STATUS_BAD_REQUEST);
                            resolve(res.body);
                        });
                });
            };

            let res = await signUp(data);
            expect(res.err).to.equal(UserValidation.ERR_INVALID_RECAPTCHA);
        });
    });
});