Setting up the test framework

Hi,

I am having trouble making the test framework (codeception) run.
I tried following the guide from: https://github.com/salesagility/SuiteCRM/tree/master/tests
I can run the demo test without failing.

vendor\bin\codecept run demo

However, if I run the install test suite it fails (after setting up the environment .yml file)

codecept run install --env firefox,mysql

The error I get is:

1) ←[35;1mUserWizardCest:←[39;22m Check the php version meets the recommended requirements.
←[37;41;1m Test ←[39;49;22m tests\install\UserWizardCest.php:testScenarioInstallSuiteCRMWithDefaultConfiguration
←[37;41;1m                                                          ←[39;49;22m
←[37;41;1m  [PHPUnit_Framework_Exception] Undefined index: ELEMENT  ←[39;49;22m
←[37;41;1m                                                          ←[39;49;22m
←[33m
Scenario Steps:
←[39m
←[1m 2. $I->waitForText("Setup")←[22m at ←[32mtests\install\UserWizardCest.php:45←[39m
 1. $I->amOnUrl("http://localhost/testcrm/") at ←[32mtests\install\UserWizardCest.php:44←[39m

If I go to my site (http://localhost/testcrm/) in the browser I see the install page, where it says “setup wizzard”, but it quickly changes to Database configuration page of the installation, and here the word setup is only in the page’s title.

But I actually just wanted to run the unit tests. I see them running on Travis CI, so I figured they worked, but when I run them all I get is:

codecept run unit
Codeception PHP Testing Framework v2.4.1
Powered by PHPUnit 4.8.36 by Sebastian Bergmann and contributors.

No other output. The result is the same even if I add the parameters from Travis CI (-f unit --steps -vvv --debug)

I am running XAMPP on Windows 7 and using Firefox’s geckodriver

I hope someone can help!

Hi Pawesome,

I believe the issue here is that the php-webdriver isn’t compatible with Firefox. You could try switching to chrome or using “-enablePassthrough false” argument when launching Selenium. Unfortunately the support for pass through mode was removed in 3.9, so you’ll have to use an older version if you want to go that route.

Hi, Dillon-Brown,

Thanks for the help! Actually I am not interested in the Selenium/webdriver tests, as I have my own setup for these. I just need the unit tests, so I don’t have to figure out how to mock the SugarBean and db myself. But are they also dependent on the other tests to function?

I got the install test running using chrome without errors, but it seems that it is skipping it anyway, don’t know why?:


There was 1 skipped test:

---------
1) ←[35;1mUserWizardCest:←[39;22m Check the php version meets the recommended requirements.
←[37;41;1m Test ←[39;49;22m tests\install\UserWizardCest.php:testScenarioInstallSuiteCRMWithDefaultConfiguration
PHP Version 7.1.1 meets the recommended requirements.
←[33m
Scenario Steps:
←[39m
 2. $I->waitForText("Setup") at ←[32mtests\install\UserWizardCest.php:45←[39m
 1. $I->amOnUrl("http://localhost/testcrm/") at ←[32mtests\install\UserWizardCest.php:44←[39m


←[30;43mOK, but incomplete, skipped, or risky tests!←[0m
←[30;43mTests: 1←[0m←[30;43m, Assertions: 0←[0m←[30;43m, Skipped: 1←[0m←[30;43m.←[0m

I found out why it skipped the test. It is because of this line in InstallTest.php

$scenario->skip('PHP Version '. PHP_VERSION .' meets the recommended requirements.');

It skips the rest of the test, if the PHP version is correct. Maybe because it has not been set up properly for SuiteCRM yet?

However, I am not interested in the acceptance tests. I only need the Unit Tests, but I still only get this output:

Codeception PHP Testing Framework v2.4.1
Powered by PHPUnit 4.8.36 by Sebastian Bergmann and contributors.

I also tried:

codecept generate:test unit Example

Followed by:

codecept run unit

But the result is the same…

I hope someone can help me!

Okay, so I figured out why it doesn’t output anything. It is because it is told to exit in entryPoints.php:65

if (empty($GLOBALS['installing']) && !file_exists('config.php')) {
    header('Location: install.php');
    exit();
}

So now I just need to know why my codeception setup exits here, while it doesn’t do that on Travis CI?
If I comment it out it fails with:

Bad data passed in; <a href="">Return to Home</a>

But it shouldn’t be necessary to comment all this out, since it is working in Travis CI.
Any help is much appreciated!

Hi Pawesome,

Please take a look the our documentation site on how to use the testing framework. There are different testing environments depending on what you need to test for. The test suite requires that you have installed SuiteCRM. You can do this manually or via the install test suite.

if you are just interested in the unit tests you need to install codeception by


composer install

then to run the following command the unit tests:


./vendor/bin/codecept run unit

Each test suite has a set of requirements. Please see the documentation for details.

The install php check exists because there is a screen which warns the user when their php version is less than the recommended.

The functional and api tests do not require selenium. The acceptance test runs with selenium or browser stack.

All browser based tests (api, functional, acceptance) require that you specify the environment variables

My recommendation for the browser based test is to create a script in the root of your SuiteCRM instance:

bash (runcodecept.sh):


#!/bin/bash
export DATABASE_DRIVER=MYSQL
export DATABASE_NAME=automated_tests
export DATABASE_HOST=localhost
export DATABASE_USER=automated_tests
export DATABASE_PASSWORD=automated_tests
export INSTANCE_URL=http://path/to/instance
export INSTANCE_ADMIN_USER=admin
export INSTANCE_ADMIN_PASSWORD=admin
export INSTANCE_CLIENT_ID=suitecrm_client
export INSTANCE_CLIENT_SECRET=secret
./vendor/bin/codecept $@

command line (runcodecept.bat)


setx DATABASE_DRIVER "MYSQL"
setx DATABASE_NAME "automated_tests"
setx DATABASE_HOST "localhost"
setx DATABASE_USER "automated_tests"
setx DATABASE_PASSWORD "automated_tests"
setx INSTANCE_URL "http://path/to/instance"
setx INSTANCE_ADMIN_USER "admin"
setx INSTANCE_ADMIN_PASSWORD "admin"
setx INSTANCE_CLIENT_ID "suitecrm_client"
setx INSTANCE_CLIENT_SECRET "secret"
.\vendor\bin\codecept  %*

then you can run


./runcodecept.sh run <test suite>

I hope this helps

1 Like

Hi djsamson,

Thanks for helping out! I have just been using the old documentation on https://github.com/salesagility/SuiteCRM/tree/master/tests/README.md, but I guess that is somewhat deprecated.

I couldn’t get the install suite to run, so I just installed it manually. I finally get some output, but it is errors:

$ codecept run unit
Codeception PHP Testing Framework v2.4.1
Powered by PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
Bad data passed in; <a href="http://localhost/codeceptcrm">Return to Home</a>
PHP Fatal error:  Uncaught Error: Class 'TimeDate' not found in C:\xampp\htdocs\codeceptcrm\include\database\DBManager.php:268
Stack trace:
#0 C:\xampp\htdocs\codeceptcrm\include\database\DBManagerFactory.php(118): DBManager->__construct()
#1 C:\xampp\htdocs\codeceptcrm\include\database\DBManagerFactory.php(143): DBManagerFactory::getTypeInstance('mysql', Array)
#2 C:\xampp\htdocs\codeceptcrm\include\utils.php(3333): DBManagerFactory::getInstance()
#3 [internal function]: sugar_cleanup()
#4 {main}
  thrown in C:\xampp\htdocs\codeceptcrm\include\database\DBManager.php on line 268

It seems it can’t find the TimeDate class, even though the codeception.yml includes

- include/*

TimeDate.php is in the include folder, but I stil get this error.
Can you help me tackle this as well?

Can I ask what version of SuiteCRM are you using? Is it the very latest? 7.10.4?

It’s the bootstrap files which include the php files, not the codeception.yml. Edit tests/unit/_bootstrap.php. you should see



<?php
// Here you can initialize variables that will be available to your test

if (!defined('sugarEntry')) {
    define('sugarEntry', true);
    define('SUITE_PHPUNIT_RUNNER', true);
}
/* bootstrap composer's autoloader */
require_once __DIR__.'/../../vendor/autoload.php';
global $sugar_config, $db;

require_once __DIR__ .'/../../include/database/DBManagerFactory.php';

require_once __DIR__ .'/../../include/utils.php';
require_once __DIR__ .'/../../include/modules.php';
require_once __DIR__ .'/../../include/entryPoint.php';
$db = DBManagerFactory::getInstance();
//Oddly entry point loads app_strings but not app_list_strings, manually do this here.
$GLOBALS['current_language'] = 'en_us';
$GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);

/* VERY BAD :-( - but for now at least tests are running */
$GLOBALS['sugar_config']['resource_management']['default_limit'] = 999999;

I use 7.10.3, have there been changes to the test setup in 7.10.4?
my _bootstrap.php file is the same as the one you have posted.

I see the changes from 7.10.3 to 7.10.4 and have tried on a new installation with the latest version, but the result is the same.

It seems that the TimeDate.php is not included until entrypoint.php is loaded.
But it is already used in DBManager, which DBmanagerFactory requires.

require_once __DIR__ .'/../../include/database/DBManagerFactory.php';

require_once __DIR__ .'/../../include/utils.php';
require_once __DIR__ .'/../../include/modules.php';
require_once __DIR__ .'/../../include/entryPoint.php';

But again, if it works for you, there should be no need for me to change the order in which the files are loaded?

If you include the TimeDate class in the bootstrap file, does it fix the issue?


require_once "include/TimeDate.php";
global $timedate;
$timedate = TimeDate::getInstance();

Then all I get is this:

$ vendor/bin/codecept run unit
Codeception PHP Testing Framework v2.4.1
Powered by PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
Bad data passed in; <a href="http://localhost/code">Return to Home</a>

The new culprit is the clean_string() function of utils.php that gets called from clean_special_arguments(), that gets called from entrypoint.php
It is when clean_special_arguments() executes this code that clean_string() fails:


if (!empty($_SERVER['PHP_SELF'])) {
    clean_string($_SERVER['PHP_SELF'], 'SAFED_GET');
}

And $_SERVER(‘PHP_SELF’) is at this point: C:/xampp/htdocs/code/vendor/codeception/codeception/codecept

So I am guessing it is the slashes that it has difficulties with?
The SAFED_GET filter is:

'SAFED_GET' => '#[^A-Z0-9\@\=\&\?\.\/\-_~+]#i', /* range of allowed characters in a GET string */

As I mentioned in the beginning I am running it on Windows 7 using Xampp.
So I am not sure how to continue, any suggestions?

I was a little hesitant to comment out the:

clean_string($_SERVER['PHP_SELF'], 'SAFED_GET');

Because I felt that it would just lead to an endless number of additional hacks to get it working.

But now that I have done it the unit tests are actually running!
Initially I got 28 errors mostly calls to undefined methods relating to imap.
So after changing my php.ini to include the imap extension I get 4 failures:
3 related to the clean_string I commented out (I think?):

file_utilsTest: Testclean_path:
-//SuiteCRM-develop/include/utils
+\/SuiteCRM-develop/include/utils

PathsTest: Get library path:
-‘C:\xampp\htdocs\code/lib’
+‘C:\xampp\htdocs\code\lib’

PathsTest: Get containers path:
-‘C:\xampp\htdocs\code/lib/API/core/containers.php’
+‘C:\xampp\htdocs\code\lib/API/core/containers.php’

And one still related to emails:

SugarEmailAddressTest: Get email guid
-‘test_email_1’
+‘e852010a-9b03-49e8-1eee-5acf52e79c2d’

Thanks for your help!

Hi Pawesome,

Since I only develop on linux, I have set up a windows machine with your development environment. On linux I don’t get this issue, however on windows there seems to be a problem.

I am glad you have it working, however, we will need to create a more permanent solution.

Happy Coding :slight_smile:

Hi Daniel,

That sounds great! I will be looking forward to it, until then this works fine for my purposes.

Thanks again!

Facing issues while running unit tests. Acceptance tests works fine though.

$ ./vendor/bin/codecept run unit
Codeception PHP Testing Framework v2.5.5
Powered by PHPUnit 5.7.27 by Sebastian Bergmann and contributors.
Running with seed:

PHP Warning: require_once(php_version.php): failed to open stream: No such file or directory in C:\xampp\htdocs\suite_tes\include\utils.php on line 45

Warning: require_once(php_version.php): failed to open stream: No such file or directory in C:\xampp\htdocs\suite_tes\include\utils.php on line 45
PHP Fatal error: require_once(): Failed opening required ‘php_version.php’ (include_path=‘C:\xampp\php\PEAR’) in C:\xampp\htdocs\suite_tes\include\utils.php on line 45

Fatal error: require_once(): Failed opening required ‘php_version.php’ (include_path=‘C:\xampp\php\PEAR’) in C:\xampp\htdocs\suite_tes\include\utils.php on line 45