Integrate Codeception to use in laravel - laravel

Is there any way of integrating codeception into laravel that i can use it in my Controllers?
For instance let's assume I've got a route Route::post('/plugins/test', PluginController#test_plugins)
In my PluginController class I want to test whether my app works correctly or not. In my case, I wanna check this after updating a plugin by using the same semantics for acceptance tests in codeception, something like:
public function test_plugins(){
$I = new AcceptanceTester($scenario);
$I->wantTo('check that ... ');
$I->amOnPage('/plugins');
$I->seeInDatabase( ... );
....
return "site works (not) correctly";
}
I am using Laravel 4.2
Cheers
Jakob

I think you are trying to do it in the wrong way. Controller never should test anything. Controller is a thing that just know what to do when the route were called. This means that you may want to call console command from the controller which will run your tests but not write testing code in controller itself.
So the steps to achieve what do you want to do are:
Create test suit as usual in your tests folder
Create the controller
Call the ./vendor/bin/codecept run unit YourTestCest

Related

Codeception, Laravel, Acceptance tests

I'm developping an acceptance test with Codeception Laravel 5.
I see in the docs that module Laravel 5 should not be used in acceptance tests.
Now, I would like to use function like: Auth::xxx, factory(User::class)->create(), etc... but those functions are not recognized.
I can use them in my funcional tests, because I include Laravel 5 Module.
Does it mean I will not be able to use them in acceptance test, or is there a trick to do it???
The documentation clearly outlines the answer to your question:
You should not use this module for acceptance tests. If you want to use Laravel functionality with your acceptance tests, for example to do test setup, you can initialize the Laravel functionality by adding the following lines of code to your suite _bootstrap.php file:
So this is what you add:
require 'bootstrap/autoload.php';
$app = require 'bootstrap/app.php';
$app->loadEnvironmentFrom('.env.testing');
$app->instance('request', new \Illuminate\Http\Request);
$app->make('Illuminate\Contracts\Http\Kernel')->bootstrap();
This means you can use the Laravel functionality in your Acceptance Tests, however, you can't use the Codeception Laravel 5 module for your Acceptance Tests.
Hopefully this clears things up.
When in acceptance testing, you have two instances, yours (codeception) and the app's (website).
This means anything laravel you use in your instance won't work in the app's instance.
Here Auth::check() has no meaning, as acceptance testing must be decoupled from the app. You should assert if you are seeing Log In or Log Out in the rendered html for example.
Eloquent is the only thing you can get away with when in acceptance testing.

Testing a CodeIgniter 2.1 controller with PHPUnit

I'm taking over a project and am trying to write some tests for CodeIgniter to run on the command line with continuous integration and there seem to be very little documentation online on testing with CodeIgniter and getting tests to run for controllers seem particularly difficult.
There's some previous answers suggesting to use FooStack, but FooStack is for CodeIgniter 1.x as best as I can gather.
I'm at the point not where I'm considering running selenium over the whole site. Has anyone managed to test controllers with CodeIgniter?
Related answers:
How to test controllers with CodeIgniter?
Using my-ciunit.
Grab a copy of https://bitbucket.org/kenjis/my-ciunit
Install PHPUnit 3.7.x
Run the installation instructions.
Presumably you didn't name the dadabase on the command line so go to application/config/testing.database.php and name your database with _test
Create your database.
Go to the tests folder and delete all the folders except controllers. All these files are examples and obviously you won't have those fixtures.
You only need the SomeControllerTest.php as a starting point. Edit it to hit a controller you actually have. I wanted to just add a basic access test.
class HomepageControllerTest extends CIUnit_TestCase {
public function setUp() {
$this->CI = set_controller('homepage');
}
public function testIndexController() {
$this->CI->index();
$out = output();
$this->assertNotEmpty($out);
}
}
I wrote two articles on testing Codeigniter both Unit and Acceptance tests. I use PHPUnit and Selenium for that.
Here are the links:
Unit tests: http://taiar.com.br/2013/11/08/testing-codeigniter-applications-with-phpunit/
Acceptance tests (Selenium): http://taiar.com.br/2014/04/21/acceptance-tests-on-codeigniter-with-phpunit-and-selenium/
I'm planning to write an article on tests at all (with testing theory) but my two first articles should help!

Testing CodeIgniter controllers

We are creating a RESTful API using CodeIgniter and I'm trying to determine how to create tests for the controllers. The controllers take some input from a client app, perform some business logic using one or more models, then output JSON.
The purpose of the tests is primarily regression testing-- to make sure that client-side engineers who are not principally web/php developers don't break something if they need to touch server code.
How would you test a controller action in CI?
I currently have two ideas:
1.) Create a test function/class that does its setup with the database then calls the controller via curl, simulating the behavior of the client.
2.) Don't test controllers, keep all logic in the models and write tests for the models.
Any thoughts on which will be more robust/easier to use? (or additional suggestions?)
As well as CodeIgniter's own testing library (CodeIgniter 2) it is possible to use PHPUnit with CodeIgniter with FooStack. If you're using CodeIgniter 2.x, it's not as straightforward to integrate as it was in CodeIgniter 1.x but I have seen it done.
FooStack itself comes with example tests covering both models and controllers, among other things, and can give you a good starting point.
Another way to test your controller, which you've said is returning JSON, might be to use the Selenium IDE. This would allow you to run simple tests that check the required input returns the expected output without worrying how it's done. FooStack or the unit testing library would probably give you a more coverage and confidence though.
If you want quality testing you need both.
One to test your code and how it handles with errors
and one to test how client itself would see potential issues.
You can validate controller also through passing the form data to your test controller like
$_POST['name'] = 'testuser';
$this->CI->index_post();
$data = output();
# Decode Response data
$actualArray = json_decode($data, true);
$this->assertNotEmpty($actualArray['status'], 'Status is empty');
like this you can validate your controller through your test/controller.

MVC TDD : How to write test for Response.Redirect?

I am new to MVC and TDD, so if it is a stupid question please spare me :)
What I am trying to do is , I have created a SignOn controller and I just want to write a Test for that controller. The thing is SignOn controller does Response.Redirect internally, that works fine if it is an proper request, but when I run my test it fails as there is no response object.
so how can I test my SignOn controller, which redirects internally ??
When you want to do a redirect you should use the actionresult: Redirect("url"). In your test you can check if the actionresult is of type RedirectResult and/or if it has the right property values.
Your action method should return a RedirectResult. If you know exactly what the URL should be, you can test the Url property.
I am not a TDD guy but something tells me that HttpContextBase is your friend : http://msdn.microsoft.com/en-us/library/system.web.httpcontextbase.aspx
Here is a good resource on that.
http://weblogs.asp.net/gunnarpeipman/archive/2011/07/16/using-moq-to-mock-asp-net-mvc-httpcontextbase.aspx
Hope this helps.
One of the patterns you can use for testing navigation code inside a controller/presenter is the ApplicationController.
Have a look at the following descriptionPEAA: Application Controller
We have implemented the Aplication Controller in our ASP.NET app.
ApplicationController.Navigate(view: "LoginScreen", argument: userId);
The ApplicationController checks which NavigationWorkflows are registered and delagetes the navigation to the correct class.
In your unit tests you can mock the NavigationWorkflow with something like rhino mocks and pass this to your ApplicationController. Then you can check if the correct navigation methods are called on your workflow.
So instead of calling Response.Redirect, you delegate the navigation responsibility to a separate class that can be replaced with unit testing.

Why, when I register my routes in an MVC test is NUnit sharing this across tests?

I am testing my routes in an mvc app. I have the following code:
using System.Web.Routing;
using MvcContrib.TestHelper;
using NUnit.Framework;
using web;
using web.Controllers;
namespace tests.web.Routes
{
[TestFixture]
public class routeTests
{
[Test]
public void Route_POSURL_MapsToPOSIndex()
{
MvcApplication.RegisterRoutes(RouteTable.Routes);
"~/POS".ShouldMapTo<POSController>(x => x.Index());
}
[Test]
public void Route_POSGetItem_MapsToPOSGetItem()
{
MvcApplication.RegisterRoutes(RouteTable.Routes);
"~/POS/GetItem/12345".ShouldMapTo<POSController>(x => x.GetItem());
}
}
}
However, the 2nd test fails stating:
System.ArgumentException: A route named 'Default' is already in the route collection. Route names must be unique.
If I run either test individually they run fine. Obviously NUnit is sharing my Routing table across tests. Why?
I know I can put my RegisterRoutes call in a TestFixtureSetup method but this doesn't answer the issue and I'd like to know what I am missing.
Am I just missing something? How come I can't find this question anywhere else on the net?
Thanks!
Matt
I don't think it's NUnit sharing the routes - I do believe that is how ASP.NET MVC works. FWIW, when testing my routes I usually put RegisterRoutes in [TestFixtureSetup]. You'd probably be okay to just do the same thing.
I found this great article from Martin Fowler which explains what is going on:
http://martinfowler.com/bliki/JunitNewInstance.html
Kudos to the xUnit Test Patterns book, as it's the one that led me to the article.
I don't know if it's because I used to be a Java guy or if I just made some assumptions. JUnit creates a new TestCase object for every single method when you run tests. That means that even global variables are reset for every single test method and are not shared.
This is not the case with NUnit. NUnit creates only one TestCase object, thus any global variables are shared. Tom, you're right in the fact that MVC creates the global variable for my routes, however, NUnit does not dump this and create a new one for each test like most other xUnit frameworks do.
I have placed the register routes code in the TestFixtureSetup method, and it works of course. I'm glad that I understand what's going on now.

Resources