My question is quite simple. I'm coming from Python world, where it's very simple to execute Selenium testing code within a program, just writing something like:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.python.org")
driver.close()
When using PHP, things are getting harder: I wrote something like that
require 'vendor/autoload.php';
class MyTest extends PHPUnit_Extensions_Selenium2TestCase {
public function setUp() {
$this->setBrowser('Firefox');
$this->setBrowserUrl('http://www.python.org');
}
public function testToto() {
$this->url('/');
}
}
...which kinda works when I execute phpunit MyTest.php.
But what I would like to do is to instanciate my test class in PHP code, and execute my Selenium commands "programmatically", like:
$myTest = new MyTest();
$myTest->testToto();
And here it sucks :(
PHP Fatal error: Uncaught exception 'PHPUnit_Extensions_Selenium2TestCase_Exception' with message 'There is currently no active session to execute the 'url' command.
So is there a way to execute Selenium code directly from PHP script without executing command line things with phpunit?
Edit: What am I trying to achieve? My project is to build a testing application which must be able to launch tests within a UI built by a end user thanks to a user friendly drag and drop builder (the user chooses which test he wants to execute first, then another, and so on). So I would like to avid ececuting phpunit commands with a ugly PHP exec: to me, the best option is to launch test case methods programmatically!
I think the pain comes from trying to use the PHPUnit Webdriver integration, without really using PHPUnit.
You can write code like your Python example by using a standalone Webdriver implementation (that does not need PHPUnit). I recommend the one written by Facebook:
https://github.com/facebook/php-webdriver
but there are some more:
http://docs.seleniumhq.org/docs/03_webdriver.jsp#php
You can also use these implementations inside PHPUnit tests. I do that as I don't like the PHPUnit Webdriver implementation.
With these it's trivial to write your example in PHP.
Well, a very nice question first of all. The short answer is yes you can, but it's too much pain. PHPUnit is just a modestly complicated, huge, scary and amazing library with a gadzillion of extensions. In the nutshell it reads the configuration, finds the tests, and runs them.
You can put a break point inside your test and trace to the top what it does, what parameters it accepts and literally simulate the whole thing. That would be the "proper" and crazy way, and the most complex too.
The simpler way would be by finding out what the test case class needs in order to run (break point & trace are always your best friends), in this particular case it turned out to be just this:
$myTest = new MyTest();
$myTest->setUp(); // Your setup will always be called prior the test.
$myTest->prepareSession(); // Specific to Selenium test case, called from `runTest` method.
$myTest->testToto();
But, even in PHPUnit_Extensions_Selenium2TestCase there is a lot of stuff that are not publicly accessible and it feels just a strike of luck. But you get the idea. Besides, simply calling a method of a test case class will result in two things: nothing happens, or you get an exception. All the fancy result tracing happens higher in the hierarchy.
I can only guess what you are trying to achieve, but probably if you ask the question about the actual problem we'd be able to help more.
Edit
exec might seem ugly indeed, but it's there for a very good reason: process isolation. There are situations when one piece of the code that is being tested changes the environment and it becomes conflicting with another piece of code, e.g., session-related, sent headers, etc. When you come across one of them, you will be praying on exec.
In your case, the easiest would be to launch the PHPUnit from the command line, but you might need to write a custom formatter to get the data in the necessary format out of it, unless you are happy with the existing ones.
Another option would be to use the the existing client for the WebDriver / Selenium and simply send commands directly to the Selenium server, I assume that's what you really need? You can find out the piece of code responsible for that in the PHPUnit extension or there's another cool project called Behat (and Mink). I believe their client is in the Behat/MinkSelenium2Driver repository. And if you don't like those, I'm sure there are other php wrappers you can find on the github, or can create your own using the existing ones as an example.
PS: Share a link to the project when it's up and running if its public.
Related
I am currently creating an automated test website where all codeception test logs can be shown. My server runs codeception through cron but the user should be able to run the test manually. My question is can I use codeception class in a php webpage without executing the commandline version? If possible anyone have an idea how?
Yes you can, it is actually also quite simple. Codeception uses the symfony console component for their command line tool. Take a look at the \Codeception\Command\Run::execute() method on how they do it. It can be a bit overwhelming at first glance, but in the end it boils down to this piece of code:
$this->codecept = new Codecept($userOptions);
if ($suite and $test) {
$this->codecept->run($suite, $test);
}
I'm trying to find specific information on how to setup Selenium with PHP bindings in a 'client-server' type of setup. I'm not even sure if what I want is possible, but I will try to do my best to describe the objective of what I am trying to achieve.
I do QA on a Web development project, where we are working with distributed team members. We need automated front end testing, and have decided that (due to a number of factors) Selenium makes the best candidate for the job.
Our team is specialized in PHP, so it makes sense to use Selenium with PHP bindings.
My biggest challenge is:
1) How do I install those PHP bindings?
2) How do I create and execute a Selenium script in PHP? This one might seem obvious, but I need to know if I need to create some sort of 'project' in PHP, or whether this requires different steps. Manuals are very clear and detailed when it concerns the default JAVA bindings, but hopelessly lacking on the PHP bindings.
3) How do I do all this, while wanting to invoke a test from a client, but having it executed by a 'server/VM'? (Keeping in mind that if the possibility were there, I would also like to be able to create tests on the server, that can execute/invoke testing activities on the desktop of the client.)
4) How do I setup a server that meets all requirements to run Selenium Server with PHP bindings?
The objective is to be able to initially create a VM (probably a Vagrant box) that would contain Selenium Server (and if needed other components) with the actual test scripts, which can be shared among team members.
This VM should both be able to execute headless tests, but ideally should also be able to drive tests on the host (if at all possible).
Technically it should support the scenario where QA finds an issue in the product, and should be able to just specify the required script to reproduce it. The developer that has the task to fix the issue should only have to run the script on his machine to actually reproduce the found error.
Eventually we would want to migrate the VM to an actual server, hence the reason we want to set it up like this from the start. This will keep things more simple once we are ready to move to a physical server.
I've been looking all over the internet for detailed documentation, but in just about any documentation many assumptions are made about already configured and set up environments. I really need a step by step explanation of how to set things up.
PHPUnit seems a bit of a weird choice to pair with Selenium, since they both cover completely different areas of testing. I have seen (again incomplete) instructions on the PHPUnit site, but that seems very clunky and our development team is not very keen on this setup.
We have people suggesting Jenkins, but I personally do not see how Jenkins would eliminate the normal setup of Selenium, which one has to go through from the start anyway.
I already have Selenium Server running as a service in a VM, I just need to know what else I need, and how I need to set it up, how to configure it. how to make things communicate, etc.
Any help/ideas would be highly appreciated.
To get this running locally, follow the instructions here:
https://github.com/facebook/php-webdriver#getting-started
Here is a sample PHP webdriver script that you can use. It will open firefox, take you to google's page and submit a search query:
// you'll need to modify this path so it points to the composer autoloader
require_once __DIR__ . '/vendor/autoload.php';
/**
* since I'm running the selenium jar locally, this is all I need.
* I just run it in the background and my php scripts connect to it and
* the tests
*/
$host = 'http://localhost:4444/wd/hub';
$driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox());
$driver->get('http://google.com');
$element = $driver->findElement(WebDriverBy::name('q'));
$element->sendKeys('Cheese');
$element->submit();
Is this the sort of detail you're looking for?
I love to save time using someone else's code. And I want to start effectively debugging my scripts, as well as scripts I inherit from other developers.
I've been reading up on debug_backtrace(), and I'm not sure if it's what I'm looking for.
Basically,when a class is instantiated I want to know what methods are being fired.
Truthfully, I'd like to know as much as possible, but knowing what's going on inside a single class would be fantastic.
<?php
require('aHugeComplicatedClass.php'); // sooooo many methods
try {
$obj = new aHugeComplicatedClass($params);
}
catch(Exception $ex){
var_dump($ex);
}
?>
From PHP's docs about debug_backtrace, it looks like I need to place the debug_backtrace() function inside each method/function within any and all classes, just to see how it was reached.
I gotta be reading this too literal. That would be a ton of modifications.
So, if I have a php file, that instantiates a class, and I know this class is extended from other classes, what's the simpliest way to debug that Object?
I would install XDebug and hook up the remote debugging to your IDE (e.g PhpStorm or Eclipse), that way you will get nice stack dumps on all errors, plus the ability to breakpoint your code and inspect the stack and all object internals at your leisure.
http://xdebug.org/
You can also use it to profile your application call chains without making any code changes (which sounds more like what you are wanting). By using the profiling options, which generate big log files, you can then load these logs into webgrind and visually inspect who's calling what in nice tree structures.
https://code.google.com/p/webgrind/
The Zend tool chain would also provide this kind of deeper debugging functionality out of the box.
Alternatively install an Application Performance Monitoring agent such as App Dynamics or New Relic for similar code-profiling. This is most useful for remote installations (i.e. production) where debugging isn't an option and profiling is expensive.
We use NuSphere PhpED for getting all such things. It can trigger debugger to stop on specified exceptions and/or errors and shows complete call-stack that may include php functions calls, php method calls, embedded functions calls and embedded method calls.
http://www.nusphere.com/products/phped.htm
I was told in the beginning that their debugger is the best and can confirm this. It stems from the OSS project
http://sourceforge.net/projects/dbg2/
With PhpED IDE we run full cycle of development -- coding, debugging, profiling, testing and uploading to the production server.
For a PHP application I'm developing, I need to read the current git revision SHA which of course I can get easily by using shell_exec or backticks to execute the git command line client.
I have obviously put this call into a method of its very own, so that I can easily isolate and mock this for the rest of my unit tests. So my class looks a bit like this:
class Task_Bundle
{
public function execute()
{
// Do things
$revision = $this->git_sha();
// Do more things
}
protected function git_sha()
{
return `git rev-parse --short HEAD`;
}
}
Of course, although I can test most of the class by mocking git_sha, I'm struggling to see how to test the actual git_sha() method because I don't see a way to create a known state for it. I don't think there's any real value in a unit test that also calls git rev-parse to compare the results? I was wondering about at least asserting that the command had been run, but I can't see any way to get a history of shell commands executed by PHP - even if I specify that PHP should use BASH rather than SH the history list comes up empty, I presume because the separate backticks executions are separate terminal sessions.
I'd love to hear any suggestions for how I might test this, or is it OK to just leave that method untested and be careful with it when the app is being maintained in future?
Although you have accepted an answer, let me post something about what the way unittests should work because even if the solution posted does work and is indeed nice, it has some backdraws.
First of all you don't want to actually execute your command, as this would test an external software. From this moment you are depending on external stuff you cannot control (what happens if I want to test your software on my pc? Do I have to instal git or any git-mock?). What you really want to do is see if the command line command is correct and is executed well.
As I struggled with this before, here is what I did: I created a class which executes shell_exec. Everywhere I want to interact with the shell, I inject the class and use it. So for testing I can mock the class and see if the correct method is executed and if the correct parameters are set.
This has many benefits:
I have one point of interacting with the shell. If anything changes in the future or if I have the need to do anything before executing the command, I can add the behaviour to the class. The PHP function is encapsulated nicely.
It works on every PC, even if the shell_exec command does not work for any reason. The tests get executed on every pc (development machines, testserver, integration server) without the need to worry about external dependencies.
Of course to validate that your software works as a whole, you have to do integration tests which do not mock anything. But this is a totally different situation. Unittests should make sure your class (or method) does what it needs to do. Sometimes this is not clear cut, as you may decide to use a real class somewhere because mocking it would lead to much overhead. But, as far as I'm concerned, it's no longer a unit test by any means if it relys on external libraries/software which may not be installed or may not work for some reason.
at least you could do something like checking for the retured string to match /^[abcdef0-9]{7}$/
I suppose if you really wanted to, you could write a dummy git and prepend its location to your environment's PATH. Have it do whatever validation you need to do, and then generate output consistent with what the real thing would do. You could conceivably even have it forward stuff to the real git, if you wanted, but then you couldn't guarantee the results.
You'd have to be careful, though....You'd want do just enough so that the class can be fooled into thinking it's really git, but if you make it behave too much like the real thing does, that amounts to writing your own half-assed version of Git.
Is there a simple "Web interface" to running PHPUnit test suites? i.e. a PHP script that runs the test on the command line, and outputs a nicely formatted HTML result.
I develop web applications, and the day-to-day workflow usually switches between the IDE and the browser. I would like to have the unit testing in the same environment.
I'm looking for something really simple and PHP based - I am planning to get into phpUnderControl (which has the functionality I'm looking for) but not yet.
I recently discovered Visual PHPUnit which looks like a very very nice interface for everyone that doesn't want to run PHPUnit from the command line:
It seems to be the next iteration of #Matt's PHPUnit Test Report
I feel your frustration - I'm a UI guy myself. Looking at the terminal too long makes my head spin. I wrote a quick little application that you might find helpful.
(source: mattmueller.me)
You can find it here: http://mattmueller.me/blog/introducing-phpunit-test-report
Cheers!
Matt
After several hours of researching recently, the best PHPUnit web frontend I have come across was https://github.com/NSinopoli/VisualPHPUnit
You can use phing to run a PHPUnitTask and then convert the output with:
PHPUnitReport - This task transforms PHPUnit xml reports to HTML using XSLT.
Example:
<phpunitreport infile="reports/testsuites.xml"
format="frames"
todir="reports/tests"
styledir="/home/phing/etc"/>
See phpunit --help for the various output formats.
The 2.3 version of PHPUnit had a chapter on this, but it is gone for some time now. You might be able to find an old copy with Google somewhere.
Since you mention this is for phpUnderControl: if you are not fixed on that, consider using Jenkins and http://jenkins-php.org.
On a side note: unless we are talking CI servers, most people I know don't use PHPUnit through a web interface. They either just use the command line or their IDE integration.
You can use Jenkins to run any kind of tasks including PHPUnit tests. It can automatically checkout your app, run the tests, build a HTML report and even email you if the build fails.
Here's the templates you need to setup Jenkins to build a bunch of interesting reports and stats from your project.
If you don't care about reformatting the output and just want to run PHPUnit from a web page, you can do so with some PHP code like this:
<pre>
<?php
$argv[0] = "phpunit.phar";
$argv[1] = '--bootstrap';
$argv[2] = 'src/load.php';
$argv[3] = "tests/MoneyTest";
$_SERVER['argv'] = $argv;
include 'phpunit.phar';
?>
</pre>
The file src/load.php is just a bunch of includes to include the classes. The output then looks like this:
#!/usr/bin/env php
PHPUnit 4.1.2 by Sebastian Bergmann.
........................
Time: 122 ms, Memory: 3.25Mb
OK (24 tests, 43 assertions)
Just ignore that first line and you can see the results.
I'm shocked that PHPUnit does not include a basic way to do this. Some classes may be dependent on the web server. Do we just not test those? Some sites have you upload your files and don't allow command line executions.
I've never seen such a web-interface... But, as you say you are always using your IDE and your webbrowser, why not think the other way ?
i.e. a possible solution would be to launch the unittests from your IDE ;-)
Which means you should be able to click on the failing tests to "jump" to either the test method, or the reason that caused the test to fail, for instance.
In the PHP + PHPUnit world, I know that Zend Studio does that -- yes, it's not free, unfortunatly ;-(
Using Eclipse PDT, a solution would be to register PHPUnit as an external tool (see or instance this blogpost : Using PHPUnit with Eclipse PDT) -- but it's quite not sexy, and you cannot click on the results to jump the the methods/tests...
Another solution would be to develop a plugin to integrate PHPUnit into Eclipse PDT (like it's been done for Zend Studio, I suppose) -- A phpunit4eclipse was created some time ago, but it's just a start, and didn't get much succes, so the author didn't work on it after releasing that...
I found this:
I stumbeld upon a post from Parth Patil, whose solution was to create an xml-report from PHPUnit and then use this xml to create your own report.
I used his solution, made it PHPUnit 3.4 compatible and also added some Reflection to see my testcase doc-comments in the report. (Note: For the refelection i use the Zend_Framework reflection class)
Ok you said you'd prefer an independent IDE solution, but just so you know there is a recent plugin that enables executing PHPUnit simply into Eclipse, and having a nice representation (like in Zend Studio, but for free).
Here is the link, the main developper replies fast to emails too if you have a problem :
http://www.phpsrc.org/wiki/
I personnaly tested some web interface, but I have always been deceived (not really practital and stable). But this is your choice.
jframework also has a nice UI for PHPUnit. It breaks the results, and shows test coverage on all files and each file separately.
It works on both web and cli, with the cli one having the benefit of dumping every test after its done (the web-based one has to wait until everything is over).
You can always use the Maven for PHP from which you can use the surefire reports (mvn site).
More info here: http://www.php-maven.org