I have been looking for a tutorial to help me integrate PHPUnit with CakePHP. Looking to use Selenium tests too so prefer PHPUnit.
I have been trying to follow the tutorial on http://cakebaker.42dh.com/2006/03/22/selenium/ but cant seem to get it work. Any good tutorials out there?
Thanks!
It's relatively easy. I use cake 1.3 from composer installation. This is how my composer.json looks like:
{
"config": {
"vendor-dir": "vendors/composer"
},
"require": {
"phpunit/phpunit": "3.7.*",
"cakephp/cakephp-1.3": "1.3",
},
"repositories": [
{
"type": "package",
"package": {
"name": "cakephp/cakephp-1.3",
"version": "1.3",
"source": {
"url": "https://github.com/cakephp/cakephp.git",
"type": "git",
"reference": "1.3"
}
}
}
]
}
Then the phpunit bootstrap.php file in tests directory:
<?php
include('../vendors/composer/autoload.php');
include('../webroot/index.php');
This is phpunit.xml form the same dir:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="bootstrap.php"
backupStaticAttributes="false"
cacheTokens="false"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
mapTestClassNameToCoveredClassName="false"
printerClass="PHPUnit_TextUI_ResultPrinter"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
strict="false"
verbose="false"
>
<testsuites>
<testsuite name="AllTests">
<directory>.</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory suffix=".php"></directory>
<file></file>
<exclude>
<directory suffix=".php"></directory>
<file></file>
</exclude>
</blacklist>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php"></directory>
<file></file>
<exclude>
<directory suffix=".php"></directory>
<file></file>
</exclude>
</whitelist>
</filter>
</phpunit>
Don't forget to load your application classes in test setup. You can do it cakephp way. For example if your controller is named calendar your calendarTest.php may look like:
<?php
/**
* Class ComponentsCommonTest
* #property calendarController $calendarController
*/
class CalendarTest extends PHPUnit_Framework_TestCase
{
/**
* #var calendarController $calendarController
*/
private $calendarController;
function setUp()
{
App::import('Core', array('View', 'Controller', 'Model', 'Router'));
App::import('Controller', 'Calendar');
$this->calendarController =& new CalendarController();
$this->calendarController->constructClasses();
$this->calendarController->layout = null;
}
}
The same for models, vendor classes and so on. Works great for me.
Unfortunately CakePHP isn't designed to work together with PHPUnit. CakePHP has switched to using SimpleTest and you'll have one of two choices, refactor your tests to work with SimpleTest or modify the core to use PHPUnit.
However it should be stated that Mark Story has stated that CakePHP 2.0 will use PHPUnit for it's testing framework, so if you can aford to wait till then that may wind up being the best option.
CakePHP 1.3 Book on Testing
Related
I'm attempting to write a unit test to test a Roslyn analyzer code fix. Things have moved on since the introduction of analyzers and editing DiagnosticVerifier.Helper.cs is no longer the way ( https://www.productiverage.com/creating-a-c-sharp-roslyn-analyser-for-beginners-by-a-beginner )
My analyzer works on mvc ControllerBase derived types yet adding the name of the AspNetCore assemblies to the reference assemblies does not resolve the issue of my test not resolving the AspNetCore namespace includes in the test source code
var test = new VerifyCS.Test();
mytest.ReferenceAssemblies = test.ReferenceAssemblies.AddAssemblies( ImmutableArray.Create(new string[] { "Microsoft.AspNetCore.Mvc"}));
error CS0234: The type or namespace name 'AspNetCore' does not exist
in the namespace 'Microsoft' (are you missing an assembly reference?)
EDIT:
fixed, using:
mytest.ReferenceAssemblies = mytest.ReferenceAssemblies.WithPackages(ImmutableArray.Create(new PackageIdentity[] { new PackageIdentity("Microsoft.AspNetCore.Mvc.Core", "2.2.5") }));
You need to use the long syntax of VerifyCS.Test:
await new VerifyCS.Test
{
ReferenceAssemblies = referenceAssemblies,
TestState =
{
Sources = {test },
//ExpectedDiagnostics = {VerifyCS.Diagnostic().WithLocation(0).WithArguments("xxx")}
}, // FixedCode = "yyy", etc.
}.RunAsync();
You can add assemblies and nuget packages:
var referenceAssemblies = ReferenceAssemblies.Default
.AddPackages(ImmutableArray.Create(
new PackageIdentity("serilog", "2.10.0"),
new PackageIdentity("Othe.Package.Name", "1.2.0")
)
).AddAssemblies(
ImmutableArray.Create(
"Microsoft.Extensions.DependencyInjection.Abstractions",
"Microsoft.Extensions.Hosting",
"Microsoft.Extensions.Hosting.Abstractions")
);
BEWARE: the nuget packages are recovered only from the feeds specified in nuget.config, so, if you're using pacakages from an special feed, like your company's DevOps feed, you need to include it in this config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
....
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="myCompanyFeed" value="https://mycompanyfeed.pkgs.visualstudio.com/_packaging/MyCoNuget/nuget/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>
Removing the <clear/> is another option, but less portable.
I am having some problems with Codeception using Yii2. I just upgraded to Yii 2.0.10 and have been using this guide
I am getting the error: Codeception\Test\Unit not found in vendor\codeception\base\shim.php. If I ocmment this class out, the next one fails which is:
namespace Codeception\Module {
class Symfony2 extends Symfony {
}
This is what've done: I created a file test.php and put it in my config folder:
<?php
// config/test.php
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/main.php'),
require(__DIR__ . '/main-local.php'),
[
'id' => 'app-tests',
'components' => [
'db1' => require(__DIR__ . '/db.php'),
]
]
);
return $config;
codeception.yaml
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
memory_limit: 1024M
colors: true
modules:
config:
Yii2:
configFile: 'config/test.php'
unit.suite.yml
class_name: UnitTester
modules:
enabled:
- Asserts
- Yii2:
part: [orm, email]
I'm completely new to Codeception, so not sure what I've done wrong
As far as I remember you have to do nothing except php vendor/bin/codecept run in directory where you have codeception.yaml.
Please note that path vendor/bin/codecept may differ in your case. Generally speaking Codeception will parse your configuration and do the magic.
It's not necessary to know but if you're interested: it parses configuration and establishes relations between namespaces and paths dynamically by using its own PSR-4 compatible class autoloader implementation.
Take a look here - https://github.com/Codeception/Codeception/blob/2.2/src/Codeception/Configuration.php#L214 and here https://github.com/Codeception/Codeception/blob/2.2/src/Codeception/Util/Autoload.php
In this situation as I upgraded from 2.0.9 -> 2.0.10. I had to composer remove yiisoft/yii2-codeception, codeception/codeception, codeception\verify, codeception\specify, codeception\base.
I copied the test folder structure over. Changed my composer.json in the root project to include:
"require-dev": {
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-gii": "*",
"yiisoft/yii2-faker": "*",
"codeception/base": "^2.2.3",
"codeception/verify": "~0.3.1",
"codeception/specify": "~0.4.3"
},
I also added the test.php and test_db.php files to /config
In a traditional Ember app, I have something along the lines of this in my ember-cli-build.js:
//ember-cli-build.js
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
babel: {
includePolyfill: true,
ignore: ['my-ember-ui/models/myFile.js'] // <-- question is here
},
Is there an equivalent to this when using an Ember Engine (or addon)? I couldn't find anything within ember-cli-babel or ember-engines.
I understand that ember-cli-build.js is just for the dummy app when using an engine, so I wouldn't make the change there. I attempted similar to above in the index.js file, but did not have any luck. The file was not ignored by babel. I need a way to ignore a particular file. Thanks!
Well, adding new rules to Cli.build.js is ok depends on what you want to do. However, I may have another solution that you can give it a try.
Babel will look for a .babelrc in the current directory of the file being transpiled. If one does not exist, it will travel up the directory tree until it finds either a .babelrc, or a package.json with a "babel": {} hash within.(.babelrc files are serializable JSON).
{
"plugins": ["transform-react-jsx"],
"ignore": [
"foo.js",
"bar/**/*.js"
]
}
or
{
"name": "my-package",
"version": "1.0.0",
"babel": {
// my babel config here
}
}
There should be another way which seems ok to use. the following does work:
babel src --out-dir build --ignore "**/*.test.js" // or simply add your file
For more information, you can read Babel document
I'm trying to build Yii2 app through unit testing and i have some questions about it.
class UsersTest extends \Codeception\TestCase\Test
{
/**
* #var \UnitTester
*/
protected $users;
protected function _before()
{
$this->users = new \app\models\Users;
}
protected function _after()
{
}
// tests
public function testGeId()
{
}
}
When i try to run this test class i have fatal error message that Users class not found. What cause of the problem and how to solve it?
There is readme file in Yii2 tests folder which tell us to setup yii2-faker and yii2_basic_tests database. What are these two things and why i should to use them?
Thank you.
It was need to create application instance in tests/_bootstrap.php. It must be following code in that file:
require('/../vendor/autoload.php');
require('/../vendor/yiisoft/yii2/Yii.php');
$config = require('config/web.php');
(new yii\web\Application($config));
Possibly you
settings:
bootstrap: _bootstrap.php
in codeception.yml is wrong? This file include vendor/autoload.php and class names resolved
defined the auto loader in the phpunit xml configuration file
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="The project's test suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
I've written a lot of django applications and become accustomed to extending unittest.TestCase and running python manage.py test app_name. Is there a similarly simple way to unit test Kanso apps? Please provide a minimal example.
Thanks.
Kanso apps are CouchDB apps. However the best bang-for-buck is to ignore CouchDB for now. The important thing is this: Kanso apps are Node.js apps. Test them the same way you would test a Node.js app. Test that they adhere to the documented CouchDB API and you will be fine.
Ideally, we might want to run tests actually in CouchDB. The JavaScript engines are different (V8 vs. SpiderMonkey); the environments are different. However in practice, it is so much easier to test Node.js code. (Also, a whole class of JavaScript bugs are absent on both platforms: third-party code setting global variables, changing built-in types, changing prototypes—those are all browser issues. Node.js and CouchDB are both pristine and predictable.)
Example
Let's make a simple Couch app that outputs "Hello world" in a _show function.
The kanso.json file:
{ "name" : "hello_world"
, "version": "0.1.0"
, "description": "A simple hello-world Couch app"
, "dependencies": { "node-couchapp": "~0.8.3" }
, "app": "app"
}
Next run kanso install which will pull in the "node-couchapp" dependency. (Notice how using the kanso command is similar to using the npm command.)
Let's make a very simple Couch app, in ./app.js:
// A Couch app that just says hello in a _show function.
module.exports = {
'shows': {
'hello': function(doc, req) {
var who = req.query.who || "world"
return "Hello, " + who
}
}
}
I ran kanso push http://example.iriscouch.com/so_hello and I can see my app here:
http://example.iriscouch.com/so_hello/_design/hello_world/_show/hello
http://example.iriscouch.com/so_hello/_design/hello_world/_show/hello?who=Stack+Overflow
Adding Tests
I like node-tap so let's use that. But the main point is, this is just some Node.js code. Test it using whatever method your prefer.
First, a quick package.json file:
{ "name" : "hello_world"
, "description": "A simple hello-world Couch app"
, "version": "0.1.0"
, "private": true
, "devDependencies": { "tap": "~0.2.3" }
}
Run npm install to get the node-tap package. (And I always have ./node_modules/.bin in my $PATH when I work on Node.js. Rather than a global install, I like to have everything I need right there in the project.
Next, perhaps a test/show_function.js file:
var tap = require('tap')
tap.test('The Couch app loads', function(t) {
t.doesNotThrow(load_app, 'No problem loading the app.js file')
t.end()
function load_app() {
var app = require('../app')
}
})
tap.test('The show function', function(t) {
var app = require('../app')
, hello = app.shows.hello
t.type(hello, 'function', 'Show function "hello" in the couch app')
var doc = {}
, null_req = {'query':{}}
, john_req = {'query':{'who':'John Doe'}}
t.equal(hello(doc, null_req), 'Hello, world', '"Hello world" by default')
t.equal(hello(doc, john_req), 'Hello, John Doe', 'Supports ?who query string')
t.end()
})
Test it by running tap test:
$ tap test
ok test/show_function.js ................................ 5/5
total ................................................... 5/5
ok
I'll change the code to return "Hello, world" hard-coded (i.e., ignore the req.query.who parameter). Notice the failing test:
$ tap test
not ok test/show_function.js ............................ 4/5
Command: "node" "show_function.js"
ok 1 No problem loading the app.js file
ok 2 Show function "hello" in the couch app
ok 3 "Hello world" by default
not ok 4 Supports ?who query string
---
file: /private/tmp/j/test/show_function.js
line: 23
column: 5
stack:
- getCaller (/private/tmp/j/node_modules/tap/lib/tap-assert.js:403:17)
- assert (/private/tmp/j/node_modules/tap/lib/tap-assert.js:19:16)
- Function.equal (/private/tmp/j/node_modules/tap/lib/tap-assert.js:160:10)
- Test._testAssert [as equal] (/private/tmp/j/node_modules/tap/lib/tap-test.js:86:16)
- Test.<anonymous> (/private/tmp/j/test/show_function.js:23:5)
- Test.<anonymous> (native)
- Test.<anonymous> (events.js:88:20)
- Test.emit (/private/tmp/j/node_modules/tap/lib/tap-test.js:103:8)
- GlobalHarness.<anonymous> (/private/tmp/j/node_modules/tap/lib/tap-harness.js:86:13)
- Array.0 (native)
found: Hello, world
wanted: Hello, John Doe
diff: |
FOUND: Hello, world
WANTED: Hello, John Doe
^ (at position = 7)
...
ok 5 test/show_function.js
1..5
# tests 5
# pass 4
# fail 1
total ................................................... 4/5
not ok
I have some projects that may help showcase testing kanso apps:
Dashboard Core Project
https://github.com/ryanramage/dashboard-core
Features:
Travis Support.
PhantomJS headless testing using NodeUnit
Since this is a module, we have a test folder, that is a seperate kanso app that uses the module. Note in the packages folder there is a symlink back to the root of the project.
Node-Couchapp Project
https://github.com/kanso/node-couchapp
Travis support
This time multiple test kanso projects in the kanso folder. Again using the symlink trick in the package directory
Like JasonSmith, I also recommend you test using Node.js where possible. However, due to the nature of CouchApps you often end up having to write unit tests to run in the browser, either because they interact with browser APIs you don't want to mock or because you need to test it works in a range of browsers.
When doing browser-based unit tests I use a few little Kanso packages I hacked together to automatically present an interface for running nodeunit test suites. It's a bit rough around the edges at the moment but gets the job done.
kanso.json
Add nodeunit and nodeunit-testrunner packages to your kanso.json file and run kanso install to fetch them from the repositories.
{
"name": "example",
"version": "0.0.1",
"description": "example app with unit tests",
"modules": ["lib", "tests"],
"load": "lib/app",
"dependencies": {
"modules": null,
"properties": null,
"nodeunit": null,
"nodeunit-testrunner": null
}
}
Notice that I've included the 'tests' directory as a module path. Any modules dropped into that directory will be used as nodeunit test suites and displayed by the nodeunit-testrunner UI.
Rewrites
You need to manually add the nodeunit-testrunner package's rewrites to your app, in my example that means editing lib/app.js to look like the following:
exports.rewrites = [
require('nodeunit-testrunner/rewrites')
];
Add some tests
Assuming we have a module lib/foo.js that looks like this:
exports.hello = function (name) {
return 'hello ' + name;
};
We could add a test by adding a module at tests/test-foo.js (this can be named anything so long as it's inside the tests directory).
var foo = require('lib/foo');
exports['test for foo.hello'] = function (test) {
test.equal(foo.hello('bar'), 'hello bar');
test.done();
};
If you then push your app and visit http://localhost:5984/example/_design/example/_rewrite/test in the browser you will be presented with a basic interface for running the test suites in the tests directory, either individually or all of them one after another.
Hope that helps.