How to Use Artisan::call() in Command Class - laravel

I have bunch of test classes and I like to call some of them based on their types or logic. I've created a command class to achive that based on the passed parameters.
The following command should find all the test classes that their names contain "Database" and "Test.php".
sail artisan testsome database
That part works without any issue, and produces an array of classes like:
$tests = ['GeneratedDatabaseFileTest', 'StatedDatabaseFileTest'];
Then I do this to call each class:
foreach ($tests as $testClass) {
Artisan::call("test --filter {$testClass}");
}
But I see this message on the terminal:
PHPUnit 9.5.13 by Sebastian Bergmann and contributors.
Cannot open file "database".
I also tried to use
exec("sail artisan test --filter {$testClass}");
but it didn't work and said
sh: 1: sail: not found
So, is there a way to run Artisan::call command in Command class, or should I try a different approach to call multiple test classes?
Thanks in advance.

Related

how can I run a single test in my terminal [duplicate]

I am struggling to run a single test method named testSaveAndDrop in the file escalation/EscalationGroupTest.php with phpunit. I tried the following combinations:
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=escalation/EscalationGroupTest.php::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=EscalationGroupTest.php::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=EscalationGroupTest::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=testSaveAndDrop
In each case all test methode in the file escalation/EscalationGroupTest.php are executed. How to select just ONE method instead?
The name of the class is EscalationGroupTest and the version of phpunit is 3.2.8.
The following command runs the test on a single method:
phpunit --filter testSaveAndDrop EscalationGroupTest escalation/EscalationGroupTest.php
phpunit --filter methodName ClassName path/to/file.php
For newer versions of phpunit, it is just:
phpunit --filter methodName path/to/file.php
I prefer marking the test in annotation as
/**
* #group failing
* Tests the api edit form
*/
public function testEditAction()
Then running it with
phpunit --group failing
No need to specify the full path in the command line, but you have to remember removing this before commit, not to clutter the code.
You may also specify several groups for a single test
/**
* #group failing
* #group bug2204
*/
public function testSomethingElse()
{
}
Here's the more generic answer:
If you are sure the method name is unique you can only filter by method name (this works for me)
phpunit --filter {TestMethodName}
However it is safer to specify the file path/reference as well
phpunit --filter {TestMethodName} {FilePath}
Example:
phpunit --filter testSaveAndDrop reference/to/escalation/EscalationGroupTest.php
Quick note: I've noticed that if I have a function named testSave and another function named testSaveAndDrop using command phpunit --filter testSave will also run testSaveAndDrop and any other function that starts with testSave*, it's weird!!
Following command will execute exactly testSaveAndDrop test.
phpunit --filter '/::testSaveAndDrop$/' escalation/EscalationGroupTest.php
Run this inside your project root directory i am using in laravel root directory.
vendor/bin/phpunit --filter 'Your method name'
Example with custom method name.
/** #test //Initilize this for custom method name, without test keyword
*
* Test case For Dashboard When User Not logged In it will redirect To login page
*/
public function only_logged_in_user_see_dashboard()
{
$response = $this->get('/dashboard')
->assertRedirect('/login');
}
Example with test keyword
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
for run phpunit test in laravel by many way ..
vendor/bin/phpunit --filter methodName className pathTofile.php
vendor/bin/phpunit --filter 'namespace\\directoryName\\className::methodName'
for test single class :
vendor/bin/phpunit --filter tests/Feature/UserTest.php
vendor/bin/phpunit --filter 'Tests\\Feature\\UserTest'
vendor/bin/phpunit --filter 'UserTest'
for test single method :
vendor/bin/phpunit --filter testExample
vendor/bin/phpunit --filter 'Tests\\Feature\\UserTest::testExample'
vendor/bin/phpunit --filter testExample UserTest tests/Feature/UserTest.php
for run tests from all class within namespace :
vendor/bin/phpunit --filter 'Tests\\Feature'
for more way run test see more
So, something like this
phpunit --filter 'EscalationGroupTest::testSaveAndDrop' EscalationGroupTest escalation/EscalationGroupTest.php
Without = and with '
https://phpunit.de/manual/3.7/en/textui.html
If you're in netbeans you can right click in the test method and click "Run Focused Test Method".
You Can try this i am able to run single Test cases
phpunit tests/{testfilename}
Eg:
phpunit tests/StackoverflowTest.php
If you want to run single Test cases in Laravel 5.5 Try
vendor/bin/phpunit tests/Feature/{testfilename}
vendor/bin/phpunit tests/Unit/{testfilename}
Eg:
vendor/bin/phpunit tests/Feature/ContactpageTest.php
vendor/bin/phpunit tests/Unit/ContactpageTest.php
The reason your tests are all being run is that you have the --filter flag after the file name. PHPUnit is not reading the options at all and so is running all the test cases.
From the help screen:
Usage: phpunit [options] UnitTest [UnitTest.php]
phpunit [options] <directory>
So move the --filter argument before the test file that you want as mentioned in #Alex and
#Ferid Mövsümov answers. And you should only have the test that you want run.
Given that you
vendor/bin/phpunit --filter=EscalationGroupTest::testSaveAndDrop
If you're using an XML configuration file, you can add the following inside the phpunit tag:
<groups>
<include>
<group>nameToInclude</group>
</include>
<exclude>
<group>nameToExclude</group>
</exclude>
</groups>
See https://phpunit.de/manual/current/en/appendixes.configuration.html
I am late to the party though. But as personal I hate to write the whole line.
Instead, I use the following shortcuts in the .bash_profile file make sure to source .bash_profile the file after adding any new alias else it won't work.
alias pa="php artisan"
alias pu="vendor/bin/phpunit"
alias puf="vendor/bin/phpunit --filter"
Usage:
puf function_name
puf filename
If you use Visual Studio Code you can use the following package to make your tests breeze.
Package Name: Better PHPUnit
Link: https://marketplace.visualstudio.com/items?itemName=calebporzio.better-phpunit
You can then set the keybinding in the settings. I use Command + T binding in my MAC.
Now once you place your cursor on any function and then use the key binding then it will automatically run that single test.
If you need to run the whole class then place the cursor on top of the class and then use the key binding.
If you have any other things then always tweek with the Terminal
Happy Coding!
You must use --filter to run a single test method
php phpunit --filter "/::testMethod( .*)?$/" ClassTest ClassTest.php
The above filter will run testMethod alone.

How to start a cron job using schedule:run manually in Laravel 5 (October CMS actually)

I know how to run cron jobs on Linux server,
I know how to use $schedule->command('foo')->daily();
I have read this document many times https://laravel.com/docs/5.0/artisan
But my question is where shall I write this line exactly
$schedule->command('foo')->daily();?
and what is $schedule variable actually? I mean is this any predefined variable in parent classes to which we can directly call if not which class we shall include in our file and how to instantiate this $schedule object.
My main concern is what is the elegant way to schedule jobs, what is the point of writing this in code where i am writing my logic because this line should run once in lifetime if I am not wrong because this will then push the job in Jobs table and then
* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1 should take care of it for rest of the lifetime
then where exactly I shall write such code which will run only once while we deploying the application on the server before starting the main cron schedule:run.
Please, someone guide me why there is no written document for how to run a scheduled task manually without writing it in a code which will be called many time during execution of a real world web application.
First, unless you're actually using Laravel 5.0, specifically, you'll want to make sure you're looking at the right version documentation (and if you are using 5.0, specifically, I highly recommend upgrading, as it's long out of support). The current version (as of this writing) is 5.5, and October CMS has been updated accordingly.
As to your question, if I'm understanding you right, you don't want a scheduled, repeating job, but simply an Artisan command. To write an Artisan command, you create a class in the Console/Commands folder (this can be generated with the make:command Artisan command) and register it in Console/Kernel.php. You can then access it by running php artisan your:command (where your:command is the name you've chosen for your command).
If you want to schedule a repeating job, you put that $schedule line into Console/Kernel.php. The $schedule variable is imported through Laravel's dependency resolver.
If you have a deployment script that you use, and you want to call that single command programmatically, you can do so with Artisan::call(), within your deploy script (be sure to import the Artisan facade):
Artisan::call('your:command');
Three Steps to take:
1) Set up cron task
http://octobercms.com/docs/setup/installation#crontab-setup
Cron will call the command scheduler every minute. Then October evaluates any scheduled tasks and runs the tasks that are due.
2) Make your console command
http://octobercms.com/docs/console/development
This command can be executed manually on the command line. And can be executed on scheduled time as explained next.
3) Register a schedule for the newly made console command in the Plugin registration class
http://octobercms.com/docs/plugin/scheduling#defining-schedules
class MyPlugin extends PluginBase
{
[...]
public function registerSchedule($schedule)
{
$schedule->command('cache:clear')->daily();
}
}
Hope this helps!
Upgrade to Laravel 8 (that is how I tested it)
run php artisan schedule:list - see what you have
run php artisan schedule:test - you will be given options
Which command would you like to run?:
[0] App\...
[1] App\...
then you type a number and see it is working

laravel phpunit how to determine which method to run

I created a UserTest class that will be used to test many user related methods and everytime a run php vendor\phpunit\phpunit\phpunit it always goes through all the methods which is not practical , i want to know if it's pôssible to run a test on a specific method .
Thank you
There are two ways to do this. To run on a specific method you can use the filter flag.
vendor/bin/phpunit --filter name_of_the_method
You can also group files together using your phpunit.xml file. Look for the tag testsuite and create a second one.
<testsuite name="API">
<directory suffix="Test.php">./tests/ApiTests</directory>
</testsuite>
Now, you can use the "testsuite" flag to run tests in that folder only.
vendor/bin/phpunit --testsuite API
Also note the "suffix" in the directory of your testsuite. This refers to what the file must end with. You can filter the files that will run the test further by adjusting your naming convention.
Just Found an answer i needed to user --filter then the name of the class then the name of the method like this
php vendor\phpunit\phpunit\phpunit --filter UserTest::testinput

Why does running phpunit not run vendor/bin/phpunit?

I am having a weird issue,
when I run
$ phpunit
I get
Fatal error: Call to undefined method PHPUnit_Framework_TestResult::warningCount() in /home/vagrant/.composer/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php on line 185
Call Stack:
0.0009 231392 1. {main}() /home/vagrant/.composer/vendor/phpunit/phpunit/phpunit:0
0.0065 743872 2. PHPUnit_TextUI_Command::main() /home/vagrant/.composer/vendor/phpunit/phpunit/phpunit:47
0.0066 744512 3. PHPUnit_TextUI_Command->run() /home/vagrant/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:106
1.1720 6818904 4. PHPUnit_TextUI_TestRunner->doRun() /home/vagrant/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:155
1.4597 16188088 5. PHPUnit_TextUI_ResultPrinter->printResult() /vagrant/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:446
However, when I run
$ ./vendor/bin/phpunit
it works as expected and runs my tests.
Maybe I have another program or something that is using the phpunit alias or something?
How can I debug to find that out?
Any ideas?
Assume you had installed phpunit from composer.json of current Laravel App.
Run this:
vendor/phpunit/phpunit/phpunit
Because the global one might be incompatible version of phpunit. Which is called and execute in the current package.
On windows I have an incompatible version installed globally.
To workaround, create "phpunit.bat" in root of project with contents:
"vendor/bin/phpunit"
This takes precendece over the phpunit in the system path.
How did you configure adding /vendor/bin to path?
I have this in my ~/.bashrc file:
PATH="$PATH:/path/to/vendor/bin"
This adds /vendor/bin/ to the end of your path, so if there is any other executable called phpunit earlier in your path - in your case, the globally installed one - it will be called instead.
To fix this, add vendor/bin to the beginning of your path in ~/.bashrc:
PATH="/path/to/vendor/bin:$PATH"
Then log out and log in or run source ~/.bashrc, and the system should then find /vendor/bin/phpunit first when you runphpunit.
On Windows, you can set an enviroment variable in your project's root directory.
Type this in your console/terminal:
set phpunit=vendor/bin/phpunit
I had the same problem with Laravel and PhpStorm, and after i typed this in my PhpStorm terminal, the problem was solved.
I've just found about about doskeys for Windows. I think they are called aliases on Mac, but they allow you to create a command as an alias for another command.
This way, I can use:
doskey macroName=macroDefinition
which in my case is:
doskey p=.\vendor\bin\phpunit
which then means I can just use the command p from my project folder for phpunit - much quicker!
For example I can now use the command:
p --filter my_single_test tests/MyExampleTest.php

Elixir TDD tests only execute when a test file is saved

I have a fresh installation of Laravel 5.1, and am trying to run automated tests using Elixir. According to documentation, I can run gulp tdd and have my tests execute automatically each time a file is saved. I have the initial ExampleTest.php which has this test:
public function testBasicExample()
{
$this->visit('/')
->see('Laravel 5');
}
This test asserts if the default welcome.blade.php file shows Laravel 5. Each time when I save the ExampleTest.php file, the automated tests do execute, and that's great. But when I change and save the welcome.blade.php file, the tests do not execute automatically.
Is this the desired behaviour or not? If not, what could be causing it?
By default elixir comes with two tasks for your test suites. One for phpunit and the other for phpspec, in your gulpfile phpUnit method is called on the mix object for phpunit test suite.
mix.phpUnit();
mix.phpSpec();
And then you need to type Gulp watchfrom terminal.

Resources