Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codeception autoloading classes

I'm having issues using the Codeception autoloader to load some abstract test classes. The reason for the abstract class is to mimic the structure of classes that are used in the application to cut down on the amount of code needed to test the application thoroughly.

Lets say I have an abstract class for testing, let say "AbstractRepositoryTester" which is only used in the "repositories" test suite (I like to separate things out for organisational purposes).

Each and every repository that I test that implements a "RepositoryContract" will have a test that also extends the "AbstractRepositoryTester" with some overridden abstract methods.

Now when doing this, the abstract class won't be loaded during testing and has to be loaded manually in a bootstrap file. There is also another abstraction that extends the vanilla Codeception test class so that I can set a few variables (namely for laracasts/testdummy).

Both classes will fail to load with out manual entry in to the _boostrap file. To add to this, the suite specific bootstrap file fails to load files or seemingly execute at all so I am forced to place all bootstrap code for all suites in to the global _bootstrap file.

I also attempted to use Codeceptions autoloading class \Codeception\Util\Autoload:: with the "load" method but it doesn't seem to work.

Right now I'm using require_once in the global _bootstrap so finally to the question:

Is there a correct way of autoloading (or just loading) a class to be used as part of a test both globally and per suite?

Am I on the right track overall in abstracting my tests like this? TDD is new to me and I am trying to better my development workflow (with help from Laracasts).

I've searched every where for an answer to load the classes I need but usually all I'll find is PHPUnit specific answers which don't appear to work. I have also peered through the Codeception documentation which feels a bit sparse on the subject and the API docs don't explain the method call usage in the case of Autoload::load

Cheers,

- Everon.

like image 234
Everon Avatar asked Jan 19 '15 07:01

Everon


People also ask

Is Codeception open source?

Codeception. Being a full-stack PHP-based testing framework, Codeception open source test automation tool allows QA teams to create and execute a plethora of tests, including acceptance, functional, and even unit ones on different browsers, using the Selenium Web Driver.


1 Answers

You can do this for your whole test suit, or just individual components. For example, for Unit tests only, do the following:

  1. Add bootstrap: my_bootstrap_file.php to tests/unit.suite.yml:
# Codeception Test Suite Configuration
#
# Suite for unit or integration tests.

actor: UnitTester
bootstrap: my_bootstrap_file.php
modules:
    enabled:
        - Asserts
        - \Helper\Unit

Call my_bootstrap_file.php something sensible like just bootstrap.php

  1. Create tests/unit/my_bootstrap_file.php
<?php
\Codeception\Util\Autoload::addNamespace('', 'src');

The directory structure should look like this:

<project root>
src/
tests/
    unit/
        my_bootstrap_file.php
    unit.suite.yml

Replace unit in the instructions above with acceptance, functional, etc. to apply it to different single components.

The PhpDoc for \Codeception\Util\Autoload::addNamespace():

    /**
     * Adds a base directory for a namespace prefix.
     *
     * Example:
     *
     * ```php
     * <?php
     * // app\Codeception\UserHelper will be loaded from '/path/to/helpers/UserHelper.php'
     * Autoload::addNamespace('app\Codeception', '/path/to/helpers');
     *
     * // LoginPage will be loaded from '/path/to/pageobjects/LoginPage.php'
     * Autoload::addNamespace('', '/path/to/pageobjects');
     *
     * Autoload::addNamespace('app\Codeception', '/path/to/controllers');
     * ?>
     * ```
     *
     * @param string $prefix The namespace prefix.
     * @param string $base_dir A base directory for class files in the namespace.
     * @param bool $prepend If true, prepend the base directory to the stack instead of appending it;
     *                      this causes it to be searched first rather than last.
     * @return void
     */
    public static function addNamespace($prefix, $base_dir, $prepend = false)

If you want this to apply to your whole test suite, not just Unit tests, use codeception.yml instead of tests/unit.suite.yml, and tests/my_bootstrap_file.php instead of tests/unit/my_bootstrap_file.php.

<project root>
src/
tests/
    my_bootstrap_file.php
codeception.yml
like image 70
CJ Dennis Avatar answered Oct 12 '22 16:10

CJ Dennis