codeception assertTrue() equivalent? - codeception

I've gone through the documentation several times, and through the source, and it doesn't work.
I'm looking for the Codeception equivalent of PHPUnit's "this->assertTrue($var)".
According to the documentation, just like that is should work, but it doesn't, "undefined method". Which helper, module or whatever do I have to activate?

Did you enabled the module 'asserts' in the corresponding suite.yml file? Like:
class_name: UnitTester
modules:
enabled: [Asserts, UnitHelper]

Here is what I wrote in the tests/_helpers/WebHelper.php
(note: WebHelper must be enabled in the .yml)
class WebHelper extends \Codeception\Module {
/**
* #param bool $a
*/
function seeTrue( $a ) {
$this->assertTrue( $a );
}
}
Then, I ran
php codecept.phar build
And now I can write
$I->seeTrue(true);

You just call
\PHPUnit_Framework_Assert::assertTrue (...);

Related

Writing an attribute trait

I'm about to choose what language to use for a new project: Perl5 or Perl6. 6 wins so far except that it is missing Moo's lazy attributes. The two implementations I found in modules are missing the key functionality. Hence, my attempt write my own implementation.
Role vs. Class
First problem I've got into is the content of attribute's .package for one declared in a role. Consider the followin:
role HOW1 {
method compose ( Mu $class ) {
note "HOW1.compose";
nextsame;
}
}
role HOW2 {
method compose ( Mu $class ) {
note "HOW2.compose";
nextsame;
}
}
multi trait_mod:<is> (Attribute:D $attr, :$mooish!) {
note "Attribute's package.HOW: ", $attr.package.HOW;
note '$*PACKAGE.HOW: ', $*PACKAGE.HOW;
$attr.package.HOW does HOW1;
$*PACKAGE.HOW does HOW2;
}
class Foo {
has $.bar is mooish;
}
role FooRole {
has $.baz is mooish;
}
The output of the script follows:
Attribute's package.HOW: Perl6::Metamodel::ClassHOW.new
$*PACKAGE.HOW: Perl6::Metamodel::ClassHOW.new
HOW2.compose
HOW1.compose
Attribute's package.HOW: Perl6::Metamodel::GenericHOW.new
$*PACKAGE.HOW: Perl6::Metamodel::ParametricRoleHOW.new
HOW2.compose
As it is clearly seen from the output, applying a role to a metaclass always works for classes and only works for $*PACKAGE.HOW with roles. Use of $*PACKAGE instead of .package could be considered a solution, but not the one I'd really like to use. (Though, if there is no better way...)
Accessor
I would like to provide lazy functionality for private attributes too. Yes, this will be availabe with self!bar syntax only, but this is a sacrifice I'm willing to make. 😉 The problem is that all the examples of custome-made accessor I found so far are using Attribute.set_value() method which is way too low-level. I'd like to have something like this:
role MooishHOW {
method compose ( Mu $class ) {
my $accessor = $class.^add_private_method( 'bar1',
method () is rw {
note self.WHO, ".bar1";
Proxy.new(
FETCH => -> $o {
$!bar1;
},
STORE => method ( $val ) {
note "Storing";
$!bar1 = $val;
}
);
}
);
callsame;
}
}
multi trait_mod:<is> (Attribute:D $attr, :$mooish!) {
$attr.package.HOW does MooishHOW unless $attr.package.HOW ~~ MooishHOW;
}
class Foo {
has $.bar is mooish;
has $!bar1 is mooish;
method to-bar1 {
note "bar1 val:",self!bar1;
}
}
my $inst = Foo.new;
$inst.to-bar1;
But $!bar1 notation doesn't compile because of the scope (MooishRole). Are there a trick I'm missing which would allow referencing a private attribute on self?
Tricky one
Perhaps it is possible to make an attribute to be a Proxy container? This would greatly simplify the overall logic of laziness implementation.
I have answered all my questions by finally achieving the target and released AttrX::Mooish module.
So far, the answer for the first question is: no. $*PACKAGE is currently the only way.
Second question: have no answer, but the final code has to rely on set_value() anyway.
The tricky one happened to be possible: set_value() does binding of an attribue to a container making it possible to bind to a Proxy object. No need to for sacrifices, private attributes can be accessed directly with lazyness working on them.
Thanks everybody, your answers let me work around some rough edges!

Codeception/PHPUnit Assert::isTrue pass with false

How come the following test pass, does this make sense?
<?php
use \Codeception\Util\Debug;
use \PHPUnit\Framework\Assert;
class TrackingCest
{
// tests
public function tryToTest(AcceptanceTester $I)
{
Debug::debug("I am really here!");
Assert::isTrue(false);
}
}
enricog is right, you need to use
$I->assertTrue(false);
But you will need to enable the Asserts module in your configuration, in acceptance.suite.yml:
classname: AcceptanceTester
modules:
enabled:
- Asserts
Besides that, there is no need to use the use statements at the top.
Your test could look like this:
<?php
class TrackingCest
{
// tests
public function tryToTest(AcceptanceTester $I)
{
codecept_debug("I am really here!");
$I->assertTrue(false);
}
}
You are actually not checking anything.
See implementation of PHPUnits Assert::isTrue method, it only returns a new IsTrue instance:
PHPUnit::Assert
To check for true with codeception you should use the methods on the injected Tester:
$I->assertTrue(false);

How to leave the browser open when a Behat/Mink test fails

I'm using the selenium2 driver to test my Drupal site using Behat/Mink in a docker container.
Using the Selenium Standalone-Chrome container, I can watch my behat tests fail, but the problem is that as soon as they fail, the browser is closed, which makes it harder for me to see what the problem is.
I'm running my tests like this:
behat --tags '#mystuff' --config=behat-myconfig.yml --strict --stop-on-failure
Is there a way to leave the remote-controlled browser open even when a test fails?
By default it is not possible.
Maybe you could find some hack to do it but it is not recommended, since each scenario should be isolated and this is not a good solution at least when running some suite with multiple tests.
For one time only see if you can use the logic for printscreen and use a breakpoint instead.
Anyway, you should use a verbose (-vvv for Behat 3) output + ide debugger to debug your code.
Finally I found a good solution for this: behat-fail-aid.
Add the fail aid to your FeatureContext and then run behat with the --wait-on-failure option:
the --wait-on-failure={seconds} option can be used to
investigate/inspect failures in the browser.
You can take a screenshot whenever an error occurs using Behat hook "AfterStep".
Consider having a look at the Panther Driver or DChrome Driver.
Here you are a shortened example considering also non javascript tests (which are faster):
use Behat\Mink\Driver\Selenium2Driver;
/** Context Class Definition ... */
/**
* #AfterStep
*/
public function takeScreenShotAfterFailedStep(AfterStepScope $scope)
{
if (99 !== $scope->getTestResult()->getResultCode()) {
return;
}
$this->takeAScreenShot('error');
}
private function takeAScreenShot($prefix = 'screenshot')
{
$baseName= sprintf('PATH_FOR_YOUR_SCREENSHOTS/%s-%s', $prefix, (new \DateTime())->format('Y_m_d_H_i_s'));
if ($this->supportsJavascript()) {
$extension = '.png';
$content = $this->session->getScreenshot();
} else {
$extension = '.html';
$content = $this->getSession()->getPage()->getOuterHtml();
}
file_put_contents(sprintf('%s%s', $baseName, $extension), $content);
}
private function supportsJavascript()
{
return $this->getSession()->getDriver() instanceof Selenium2Driver;
}

Authentication test running strange

I've just tried to write a simple test for Auth:
use Mockery as m;
...
public function testHomeWhenUserIsNotAuthenticatedThenRedirectToWelcome() {
$auth = m::mock('Illuminate\Auth\AuthManager');
$auth->shouldReceive('guest')->once()->andReturn(true);
$this->call('GET', '/');
$this->assertRedirectedToRoute('general.welcome');
}
public function testHomeWhenUserIsAuthenticatedThenRedirectToDashboard() {
$auth = m::mock('Illuminate\Auth\AuthManager');
$auth->shouldReceive('guest')->once()->andReturn(false);
$this->call('GET', '/');
$this->assertRedirectedToRoute('dashboard.overview');
}
This is the code:
public function getHome() {
if(Auth::guest()) {
return Redirect::route('general.welcome');
}
return Redirect::route('dashboard.overview');
}
When I run, I've got the following error:
EF.....
Time: 265 ms, Memory: 13.00Mb
There was 1 error:
1) PagesControllerTest::testHomeWhenUserIsNotAuthenticatedThenRedirectToWelcome
Mockery\Exception\InvalidCountException: Method guest() from Mockery_0_Illuminate_Auth_AuthManager should be called
exactly 1 times but called 0 times.
—
There was 1 failure:
1) PagesControllerTest::testHomeWhenUserIsAuthenticatedThenRedirectToDashboard
Failed asserting that two strings are equal.
--- Expected
+++ Actual
## ##
-'http://localhost/dashboard/overview'
+'http://localhost/welcome'
My questions are:
Two similar test cases but why the error output differs? First one the mock Auth::guest() is not called while the second one seems to be called.
On the second test case, why does it fail?
Is there any way to write better tests for my code above? Or even better code to test.
Above test cases, I use Mockery to mock the AuthManager, but if I use the facade Auth::shoudReceive()->once()->andReturn(), then it works eventually. Is there any different between Mockery and Auth::mock facade here?
Thanks.
You're actually mocking a new instance of the Illuminate\Auth\AuthManager and not accessing the Auth facade that is being utilized by your function getHome(). Ergo, your mock instance will never get called. (Standard disclaimer that none of the following code is tested.)
Try this:
public function testHomeWhenUserIsNotAuthenticatedThenRedirectToWelcome() {
Auth::shouldReceive('guest')->once()->andReturn(true);
$this->call('GET', '/');
$this->assertRedirectedToRoute('general.welcome');
}
public function testHomeWhenUserIsAuthenticatedThenRedirectToDashboard() {
Auth::shouldReceive('guest')->once()->andReturn(false);
$this->call('GET', '/');
$this->assertRedirectedToRoute('dashboard.overview');
}
If you check out Illuminate\Support\Facades\Facade, you'll see that it takes care of mocking for you. If you really wanted to do it the way that you were doing it (creating an instance of mock instance of Auth), you'd have to somehow inject it into the code under test. I believe that it could be done with something like this assuming that you extend from the TestCase class provided by laravel:
public function testHomeWhenUserIsNotAuthenticatedThenRedirectToWelcome() {
$this->app['auth'] = $auth = m::mock('Illuminate\Auth\AuthManager');
// above line will swap out the 'auth' facade with your facade.
$auth->shouldReceive('guest')->once()->andReturn(true);
$this->call('GET', '/');
$this->assertRedirectedToRoute('general.welcome');
}

How to add comments to fenced code block within doxygen documentation

I am using fenced code blocks in Doxygen using the markdown syntax. This makes it easy to add a simple code example, like this:
~~~~~{.cpp}
void doSomething()
{
}
~~~~~
When I try to add comments into the fenced code block using two forward slashes, Doxygen seems to remove the slashes. So when I write this:
~~~~~{.cpp}
void doSomething()
{
// This function should do something
}
~~~~~
I get this output:
void doSomething()
{
This function should do something
}
How can I tell Doxygen to keep the comments in the fenced code block?
EDIT:
The complete file looks like this (we use the standard Doxygen extension of .dox for documentation-only files):
/*!
\page PATTERN_SAMPLE Sample
~~~~~{.cpp}
void doSomething()
{
// This function should do something
}
~~~~~
*/
The result looks like this:
Try with \code
\code{.cpp}
class Cpp {};
\endcode
I encountered the same issue. No need to change code format. You can specify STRIP_CODE_COMMENTS as NO: this setting outputs the source code with the comment.
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
# special comment blocks from generated source code fragments. Normal, C++ and
# Fortran comments will always remain visible.
# The default value is: YES.
STRIP_CODE_COMMENTS = NO