I have a Codeigniter framework on place, which I'm building a test framework on top of it.
Once of the features of the test framework is to remotely deploy test suits. Therefore, I'm trying to deploy a Python test suit I wrote from the webpage:
public function deploy_test()
{
if( !$this->input->is_cli_request() ) {
echo json_encode(system("python test_suit.py"));
}
}
from my controller, so, when a test deployed, I want to run it. For proof of concept I did that way. However, the job never get deployed, nor is the command line ever executed.
When I ran that piece of code from the terminal, it works as supposed. What am I missing here?
Thank you
** Its curious to mention when I execute ls -l it works ...
Basically, this is a bad idea - if the host has declined access to executing things on the server (after all, how does it know that your code is not malicious), you really shouldn't try to work around this, at least without speaking to your provider and asking them if they're ok for you to do this!
After all, executing an LS isn't really going to be malicious, but you could try and execute a Python script that 'rm -rf's the server.
Now, you might be able to find a work around, but to my mind, the question is should you? They might interpret this as a hacking attempting.
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);
}
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.
I have a test suite for my cakephp web app using the cakephp phpunit wrapper provided in 2.x. I would love to merge my test suite into production and be able to test periodically in production via a test database. My issue is as followed:
CakePHP uses a file called test.php to run the test suite and index.php to run the site. I want to lock access to my test suite behind our administrative login, because I don't want anyone to be able to run my test suite on our site just by navigating to www.myapp.com/test.php
I cannot find any information about how to do this. Its possible that no one is doing this because this is a bad strategy that I have propose. If that is the case, could someone please direct me to a better cakephp testing strategy. Sorry, I'm new to building tests.
Thank you to anyone that can help.
Don't use the web test suite but use the command line instead. See "Running tests from the command line".
cake test
Also running tests on a production system might not be a good idea either as it can put some load on the server and the site might respond very slow while the tests run.
If you run the tests via command line you can use the command "nice" and set how much CPU load the command you're going to execute is allowed to cause.
Here we set up a server that we run right next to production called development. These two servers are exact matches (I hope...) and we run our test suite from there. I still run them through the browser, but I agree that the command line works as describe by #burzum. Testing on live is a bad idea. It could mess things up and is not worth the risk for us.
I've been working on a CMS for a few years and I actually implemented a jquery-based console in the admin area, where you could do some handy things like enable/disable modules and so on.
I recently fiddled around with drupal and decided to install cygwin along with drush.
I tried googling around but figured this might be an unusual question: How does one go about creating a CLI for a php-based CMS? And exactly how does exactly drush worK? I mean, I know that it runs from the command line as a batch script in windows. But how does it interact with PHP and so on?
I do know some basic C# but this shouldn't be very hard once i figure out how this fits together. (php, sql, etc).
Any help is appreciated, thanks in advance :)
You can run a php cli from the terminal only when you have php compiled with cli support. Additional you need to specify an interpreter and pass the path to the script as argument. But you can also use a shebang #!/path/to/php. A better practise would be to use the env variable and not hardcode the path to php: #!/usr/bin/env php. Read here about it: http://tech.vg.no/2012/02/21/dont-hardcode-php-executable-path-in-shebang/.
Basically you can write a simple CLI shell with a infinite loop plus a 'exec()' or 'shell_exec()' PHP functions. you should get the user commands and send it to shell_exec() function for execute in a system shell and return the output of that to the user.
i.e:
while(TRUE){
if($input != 'exit')
$output=shell_exec($input);
else
break;
echo $output;
}
you can add other options and customize this simple loop.
you can call external programs with 'exec()' function.
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.