Codeception autoloading classes
Asked Answered
N

1

8

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.

Niu answered 19/1, 2015 at 7:24 Comment(3)
Since jan 19, 2015, I hope you found an answer. Can you reflect on your question and explain if and how you made this work? It was a top hit on duckduckgo for meCrane
I'm afraid I didn't find a solution iirc. These days I stick to standard phpunit. I suspect I wasn't orchestrating my test assets correctly in the project I encountered this on.Niu
Too bad mate, Thanks for replying anyway. Maybe if I find a solution I will post something about it on this question.Crane
A
1

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
Arrangement answered 11/9, 2019 at 4:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.