Narco Tanks of Mexico

https://s.w.org/images/core/emoji/12.0.0-1/72×72/1f51e.png

Time to do a report on a war theater where heavily armored vehicles shoot it out with each other in city streets: Mexico.

(You were thinking Ukraine? Probably an update on that next week.)

Cartel violence waxes and wanes, and regular readers know that the cartels are heavily armed. Even so, it may come as a shock to many that Mexican drug cartels have their own “tanks” (AKA “Monstruo”), i.e. up-armored civilian vehicles more accurately described as technicals or armored cars.

Mexican police recently captured one in Jalisco.

Mexico’s Guardia Nacional in Jalisco have captured a homemade ‘narco tank’ thought to be used by one of the country’s most powerful drug cartels.

The officials shared the news to Twitter after it was found in the area of Jalisco on 12 April.

According to the Mexican police, the vehicle was harbouring 2,000 rounds of ammunition.

In Texas, we call that “a good start.”

The heavy metal plated vehicle is thought to be owned by the Cartel Jalisco Nueva Generacion [CJNG], who operate in the area, as reported by The Star.

Painted green to blend in with surroundings, the tank is heavily armoured, with protective metal casing around the driver’s sider.

Publication Borderland Beat noted that the tank was discovered while being transported inside of a trailer.

The trailer limitation is probably why it seems unusually narrow.

Here’s a video covering various captured cartel narco tanks (though the voice-over isn’t the best).

Here’s a shorter video from several years ago showing various monstruos, mainly from the 2010-2011 timeframe.

This video shows still more footage, including (about 1:50 in) modern CJNG vehicles that not only look more professionally constructed, but have red-blue flashing lights and a cartel logo on the side, which does rather suggest they’re not trying to keep a low profile. Also includes combat footage of CJNG blowing away Northeast Cartel (CDN) rivals through their own gunholes.

Here’s a tweet that shows video of two other captured Nueva Generacion vehicles in 2019:

And here’s one with a handy diagram:

Some enterprising hobby company could probably sell models of these things…

Lawrence Person’s BattleSwarm Blog

11 Pistol Shooting Drills to Improve Accuracy

https://cdn.athlonoutdoors.com/wp-content/uploads/sites/8/2015/05/gbg-accuracy-1-150×150.1511985468.pngPistol Shooting drills
Pistol Shooting drills
Pistol Shooting drills
Pistol Shooting drills
Pistol Shooting drills

Of all of the firearms in our arsenal, the handgun can be the most challenging to master. It is small with a short sight radius and generally has a trigger that requires more pressure than the gun weighs. Almost always found with “open sights,” mastering a handgun requires mastering many moving parts. Fear not though, because by dividing handgun shooting into a few sections, we can do pistol shooting drills to improve our overall shooting.

Trigger Control

We often hear the phrase “trigger control” used when discussions of accuracy arise. Few times, however, is it given sufficient attention. The truth is that pistols for the most part are accurate. It’s our manipulation of the weapon that interferes with its ultimate capability. Here are some solid trigger control drills to help you improve.

Pistol Shooting Drill #1: Brass On The Front Sight

This is always easier with the help of a partner. Start by unloading your weapon and remove the magazine if possible. Reset the action on your pistol and have your partner balance a piece of spent brass on the front sight. Now, execute a smooth, clean press of the trigger. If you do this correctly, the front sight will not dip or move and the brass will stay in place. If the brass falls off, you are generally jerking the trigger and causing movement in the gun. That movement translates into missed shots. The key to keeping the brass steady is a smooth, continuous trigger press with a clean “break” at the end.

Pistol Shooting Drill #2: Keep the Slack Out

The more we move the trigger, the higher the probability that we will miss our shot. The trigger press is composed of three stages:

  1. The Slop – The distance the trigger travels to the rear before you encounter resistance.
  2. The Slack – The distance the trigger will still travel while under tension prior to firing.
  3. The Shot – Where the trigger finishes its travel and ultimately fires the weapon.

In our initial press of the trigger, we will experience all three stages of the trigger motion. However, after the initial press, the trigger will reset. The distance required for reset generally takes it only as far as our “slack” point. Do not allow the trigger to travel any further forward than necessary.

Pistol Shooting Drill #3: Empty Your Weapon and Press the Trigger

With your support-side hand, rack the slide and, as it is moving forward, relax your trigger finger. The tension of the trigger will push forward and allow it to reset. Only let the trigger move as far forward as it has to. Continuous dry-fire practice with this drill will familiarize you with how far your trigger needs to travel. We always look to avoid letting the trigger move all the way forward or having our trigger finger coming off. This generally ends up in a “slap” of the trigger on subsequent shots, which will interfere with accuracy.

Pistol Shooting Drill #4: Pencil Drill

Another common problem regarding the trigger is when it is not pressed directly to the rear. Many times, the firing-side hand over-grips the gun and causes the finger to arc as the trigger is pressed. This is called smearing the trigger and usually ends up causing shots to break to the support side. The trigger should be pressed with a direct and careful motion. A great pistol shooting drill to practice this is to place a pencil on the web of your thumb with the eraser on your trigger finger. Slowly and smoothly press the pencil toward you with the intention of keeping it on the web of the thumb. This drill will not only help you visualize a good press but can also create strong habits.

Follow-Through

Follow-through is the act of maintaining a steady platform to send follow-up shots on target. The challenge comes in the form of anticipation or flinch. Especially true with newer shooters, the anticipation of the next shot can cause a flinch response to the weapon. This causes muzzle dip, which never helps accuracy. Two proven drills to deal with this challenge are these:

Pistol Shooting Drill #5: Ball and Dummy

One of the most classic pistol drills, the Ball and Dummy drill is designed to help eliminate flinch. The drill is generally done with a partner to assist. While the shooter is turned away, the partner will place their weapon in a state of readiness. It will either be set with a round in the chamber or reset without a round. Either way, the trigger will function. The shooter is turned back around and given the weapon. They point in and press as if they were shooting a bullseye. If the weapon is unloaded, the trigger will click yet the muzzle should not dip. If there is a noticeable dip, it is a sign of anticipating the shot. Continue this drill with an occasional live round placed in the chamber so as to keep the shooter off-balance. Approximately 75 percent of the time it should be empty, however. This is a solid drill for learning to overcome the anticipation of the shot firing.

Pistol Shooting Drill #6: Single-Shot Drill

Similar to the Ball and Dummy drill, this exercise works on eliminating shot anticipation. This drill can be practiced without any assistance, making it easy to manage. Load one round into the weapon and then remove the magazine. Point in and fire the round on target. Settle in for a second shot and press the trigger. Watch your front sight intently for signs of dipping. This is equally effective as a tool for self-diagnosis.

Sight Picture & Alignment

There are many theories and methods of shooting when it comes to the sights. At the most fundamental and reliable level, though, we look to align the sights on target while intently focusing on the front sight. The rear sights should be slightly blurry as will be the target. The front sight should be crystal clear. Here are a few reliable drills to build confidence.

Pistol Shooting Drill #7: Bench Shooting

One of the best ways to learn certain components of shooting is to minimize the need to focus on other parts. By shooting from a benched position, you are able to eliminate the need to stabilize yourself in order to make good shots. This is a confidence builder as well as a drill to help you build good sight alignment habits. Sit at a bench with your arms resting on a shooting bag. Acquire a solid sight picture and alignment. Take your time and fire shots with the intent of managing perfect sights throughout the process.

Pistol Shooting Drill #8: Figure-8 Drill

One of the challenges we face is the feeling that our sights are all over the place as we begin to make a shot. For the most part, that is just our perception and not reality. With good mechanics, you can make accurate shots consistently. A drill to show you this, as well as to work on trigger control, is the Figure-8 drill. At about 6 yards, point in at your target, then take all of the slop and slack out of the trigger. Intentionally move the front sight 6 to 8 inches in a figure-8 over the bullseye. Now, as you come across the bullseye, break your shot and reset your trigger to shoot again. Continue this for 5 or 6 shots. What you will find is that you are much more accurate than you may think. By managing the trigger well, it allows for quite a bit of motion while still maintaining good accuracy.

Master Class

The goal is always to bring these components together. Unless you are a static bullseye shooter, there will be many moving parts to making a shot. Here are a few drills designed to start mixing components without overwhelming yourself.

Pistol Shooting Drill #9: Ragged Hole Drill

The Ragged Hole drill is another classic. From 6 yards, you will slow-fire 5 rounds into a single point on your target. Do your best to focus on a small portion of the target. Better yet, get a target that has 1- to 2-inch dots on it as focal points. Take your time and use the exact same point of aim each time. Do not chase your shots or try to make corrections. If you manage your trigger and sights well, you should end up with a single, ragged hole. If your shots are spread out, it is a sign that you need to polish up on one or more of the basics.

Pistol Shooting Drill #10: Shrinking Targets 

Similar to the Ragged Hole drill, the goal here is to start shrinking your shot groups. Find or make a target that has 3 or 4 circles on it, each a little smaller than the previous one. From 6 yards, fire 5 rounds into each circle. The goal is to have all the rounds inside the circle. As you master one circle, move to the next smaller one, and so on. This is as much a confidence builder as it is a skill builder.

Pistol Shooting Drill #11: Single Shot From Draw

Our final drill starts to bring all of the fundamentals together. From a holstered position, smoothly draw your weapon and fire one round onto a bullseye. Do good after-action drills, then reholster. Repeat this 10 times and then reset yourself. The goal is to be able to shoot solid shots while mixing in the motion of drawing. If your groups begin to open up, slow down. If you are shooting ragged holes, then strive to increase your pace. This is a solid drill to start mixing the fundamentals.

Shooting a handgun can be a frustrating challenge. One minute you are shooting bullseyes and the next you are off. As with all shooting, it always comes back to the fundamentals. By practicing these pistol shooting drills, you can improve individual skills and ultimately bring them all together.

The post 11 Pistol Shooting Drills to Improve Accuracy appeared first on Tactical Life Gun Magazine: Gun News and Gun Reviews.

Tactical Life Gun Magazine: Gun News and Gun Reviews

Project Appleseed Announces 2022 Schedule of Ohio Events

https://www.buckeyefirearms.org/sites/buckeyefirearms.org/files/styles/slideshow/public/field/image/appleseed-2022.jpg?itok=wq6fsSiT

Project Appleseed 2022

Appleseed only took a short break in Ohio. Even with the cold and the snow this winter, Ohio Appleseed is still having events and putting riflemen and women’s skills to the true elements test.

Project Appleseed is a nonpartisan, nonprofit national organization teaching Americans about their shared heritage and teaching fundamental rifle skills at a 2-day clinic. Most events are at a distance of 25m.

Appleseed teaches field rifle marksmanship skills using a USGI web sling; no bipod, sand bags or tables. This is done over the course of a 2-day weekend clinic. During the clinic participants will also hear the heritage every American shares that dates back to April 19, 1775.

The heritage shared over the weekend will include Paul Revere’s ride, Lexington Green, and the North Bridge. You’ll also hear some interesting bits of history on specific people that made their mark during the day.

Who should participate in an Appleseed event? ANYONE and EVERYONE! Whether you’re new or experienced, a man or a woman, adults or children. When it comes to bringing a child, they must be able to handle the rifle safely, be safe overall and follow directions. We’ve had students of all ages, from 8 to 80.

If you’ve been an Appleseed event in past and earned that coveted Rifleman patch, put your skills to the true test at distance. Appleseed has events allowing shooting out to 400 yards, called Known Distance events.

In the past couple years, Appleseed also started having Pistol Clinics. Put your pistol skills to the test with a qualification test similar to the rifle clinics. There are several pistol clinics being offered across Ohio. Don’t worry, you won’t miss out on the heritage either. The heritage from April 19, 1775 is included in these clinics. There is an age limit for the pistol clinics in Ohio, a minimum age of 18 years old.

Feel free to visit our website at appleseedinfo.org for more information including the national schedule and current pricing. Click here for events in Ohio. For questions related to Ohio, send an email to OH@appleseedinfo.org.

Project Appleseed greatly appreciates the support of Buckeye Firearms Association.

Buckeye Firearms Association

ConservativesofTikTok Formed To Share Videos Of Conservatives Sharing Sensible Opinions Everyone Agrees With

https://media.babylonbee.com/articles/article-10934-1.jpg

U.S.—A Twitter account called “ConservativesofTikTok” made its debut over the weekend, racking up thousands of followers and retweets. The account is reportedly a direct response to “LibsofTikTok” which shares content from pink-haired leftists screaming degenerate things into their cameras. The new account instead shares content from normal-looking conservatives sharing sensible opinions pretty much everyone agrees with.

“This conservative says that men are men and women are women” posted @ConservativesofTikTok as it shared a Tik Tok video of a conservative man discussing the alleged differences between men and women.

Another video features a middle class dad mowing his lawn while wearing New Balance sneakers and talking about how low taxes are a good thing.

“ConservativesofTikTok MUST be stopped,” said one Leftist while watching a video featuring a stay-at-home mom talking about how teachers shouldn’t talk with kindergartners about sex. “If these get out, everyone will find out how normal and sensible conservative opinions are!”

Videos shared by ConservativesofTikTok have been met with a hurricane of rage and righteous indignation. Twitter user @unholybanana666 commented, “i can’t believe anyone believes that!! what a DUMMY!!!!111” and user @iamaman said, “what a ****** maybe he should read a ***! I CANT EVEN!!!”

According to sources, conservative users are mostly confused by the account, which they said doesn’t show them in a bad light at all.

“Yes, this is what we really believe,” posted @fakeDonaldTrump in response to the Twitter account. “Why is this controversial?”

Conservatives have expressed some worry that the account will make them look lame since most videos feature boomer Dads in struggling to figure out how to work the camera. 


Mandy is absolutely triggered by Twitter’s possible takeover by Elon Musk. She attends a Twitter-sponsored therapy session to help her cope.

Subscribe to The Babylon Bee on YouTube

The Babylon Bee

Finding Differences Between MySQL Servers

https://www.percona.com/blog/wp-content/uploads/2022/03/Finding-Differences-Between-MySQL-Servers.pngFinding Differences Between MySQL Servers

Finding Differences Between MySQL ServersWhen one is responsible for promoting application development from Dev through the various environments such as QA, UAT, etc., through Production, it is often useful to ensure that configurations in test environments are comparable to the final production environment.  This is especially true with systems where a team of DBAs manage the servers.

Obviously, the difference in performance could be due to differences in hardware, storage, networking, software configuration, etc.  The question is how does one quickly and efficiently find the differences without having to run a lot of different commands and compare the output.  Fortunately, our Percona Toolkit has a couple of utilities that can make this much easier.  When you are tasked with supporting large numbers of servers, efficiency is paramount and this is where the toolkit can really help you!

You can find more information on the Percona Toolkit here: https://www.percona.com/software/database-tools/percona-toolkit

Let’s look at a few utilities that can help you spot differences in servers.  The first tool we will look at is pt-summary (https://www.percona.com/doc/percona-toolkit/LATEST/pt-summary.html).

The pt-summary tool will give you a summarized view of the server hardware.  It runs a series of Linux commands and formats the output into an easy-to-consume format.  You will get details on the following:

  • Operating System & Linux kernel
  • Virtualization
  • CPU (number of cores, speed, models, caching)
  • Memory consumption, swappiness, etc.
  • Mounted filesystems (mount points, size, usage, format, etc.)
  • Disk schedulers
  • Disk partitioning
  • Logical Volumes
  • RAID
  • Network configuration
  • Network traffic statistics
  • Network connections
  • Top processes
  • CPU utilization

By running the same report on the servers, you can spot-check differences in the hardware and Operating System.

When you want to find out differences in MySQL configuration, the toolkit has the perfect tool for this.  It is called pt-config-diff (https://www.percona.com/doc/percona-toolkit/LATEST/pt-config-diff.html).

This utility can connect to different servers and look at their configuration via MySQL Server Variables and then perform a “diff” on the values.  The tool creates a simple and concise output showing any differences between the servers.  Any differences will be immediately obvious.  Below is an example of the output:

2 config differences
Variable                  my.primary.cnf  my.replica.cnf
========================= =============== ===============
datadir                   /tmp/12345/data /tmp/12346/data
port                      12345           12346

Usage of these two utilities will allow you to quickly and easily find differences in either hardware or MySQL configuration between two or more servers.  These are the two tools that I always go to when I need to understand why two servers that are supposedly the same do not perform similarly.

Percona Database Performance Blog

Tandem Shower

https://theawesomer.com/photos/2022/04/tandem_shower_t.jpg

Tandem Shower

 | Pledge | Link

Like to share a shower with your sweetheart but hate fighting for warm water? Boona’s cleverly-designed dual shower head attaches to your existing water source and holds in place with a tension rod, distributing water evenly from both ends of your shower. Each head is adjustable for people of different heights.

The Awesomer

Access Patterns for MySQL

Access patterns intrigue me because it seems that everyone knows what they are and talks about them, but there’s also very little written about them—in MySQL literature, at least.
That’s why I set out to enumerate a list of access patterns (specific to MySQL).
Since there’s no apparent standard for access patterns, I cannot say how my list measures up, but after spending most my career with MySQL, I know this: it is necessary to consider these access patterns when evaluating and improving MySQL performance.
Simply put: you cannot ignore how the application accesses MySQL.

Planet MySQL

Learn how to start Testing in Laravel with Simple Examples using PHPUnit and PEST

https://laravelnews.imgix.net/images/pest-php-dark.png?ixlib=php-3.3.1

When talking about automated tests or unit tests in any programming language, there are two groups of people:

  • Those who don’t write automated tests and think they’re a waste of time
  • Those who do write tests and then can’t imagine their work without them

So, with this article, I will try to convince the former camp to look at the other side and see the benefits, and see how easy it is to start with automated testing in Laravel.

First, let’s talk about the “why” and then I’ll show a few very basic examples of the “how”.


Why You Need Automated Tests

Automated tests are not complicated: they just run parts of your code for you and report any errors. That’s the most simple way to describe them. Imagine that you’re launching a new feature in your app, and then a personal robot assistant would go and manually test the new functionality for you, also testing if the new code didn’t break anything from the old features.

That’s the main benefit: re-testing all the features automatically. And it may seem like extra work, but if you don’t tell that “robot” to do it, then you should do it manually yourself, right? Or do you just launch the new features without too much testing, hoping that the users would report the bugs? I call that method sarcastically “fingers-crossed-driven development”.

With every new feature of your app, automated tests pay off more and more.

  • Feature 1: saves X minutes of testing manually
  • Feature 2: saves 2X minutes – for feature 2 and feature 1 again
  • Feature 3: saves 3X minutes…
  • etc.

You get the idea. Imagine your application in a year or two, with new developers on the team who wouldn’t even know how that “Feature 1” works or how to reproduce it for testing. So, your future self will thank you massively for writing the automated tests.

Of course, if you think that your project is a very short-term one and you don’t care that much about its future… Nah, I believe in your good intentions, so let me show you how it’s easy to start testing.


Our First Automated Tests

To run the first automated test in Laravel, you don’t need to write any code. Yup, you’ve read that right. Everything is already configured and prepared in the default Laravel installation, including the first real basic example.

You can try to install a Laravel project and immediately run the first tests:

1laravel new project

2cd project

3php artisan test

This should be the result in your console:

1 PASS Tests\Unit\ExampleTest

2 that true is true

3 

4 PASS Tests\Feature\ExampleTest

5 the application returns a successful response

6 

7Tests: 2 passed

8Time: 0.10s

If we take a look at the default Laravel /tests folder, we have two files.

tests/Feature/ExampleTest.php:

1class ExampleTest extends TestCase

2{

3 public function test_the_application_returns_a_successful_response()

4 {

5 $response = $this->get('/');

6 

7 $response->assertStatus(200);

8 }

9}

There’s no need to know any syntax, to understand what is happening here: loading the homepage and checking if the HTTP status code is “200 OK”.

Also notice how the method name test_the_application_returns_a_successful_response() becomes readable text when viewing the test results, just replacing the underscore symbol with a space.

tests/Unit/ExampleTest.php:

1class ExampleTest extends TestCase

2{

3 public function test_that_true_is_true()

4 {

5 $this->assertTrue(true);

6 }

7}

This looks a bit pointless, checking that true is true? We’ll talk about unit tests specifically, a bit later. For now, you need to understand what is generally happening in every test.

  • Each test file in the tests/ folder is a PHP Class extending the TestCase of PHPUnit
  • Inside of each class, you may create multiple methods, usually one method for one situation to be tested
  • Inside of each method, there are three actions: preparation of the situation, then action, and then checking (asserting) if the result is as expected

Structurally, that’s all you need to know, everything else depends on the exact things you want to test.

To generate an empty test class, you just run this command:

1php artisan make:test HomepageTest

It would generate the file tests/Feature/HomepageTest.php:

1class HomepageTest extends TestCase

2{

3 // Replace this method with your own ones

4 public function test_example()

5 {

6 $response = $this->get('/');

7 

8 $response->assertStatus(200);

9 }

10}


What If Tests Fail?

Let me show you what happens if the test assertions don’t return the expected result.

Let’s edit the example tests to this:

1class ExampleTest extends TestCase

2{

3 public function test_the_application_returns_a_successful_response()

4 {

5 $response = $this->get('/non-existing-url');

6 

7 $response->assertStatus(200);

8 }

9}

10 

11 

12class ExampleTest extends TestCase

13{

14 public function test_that_true_is_false()

15 {

16 $this->assertTrue(false);

17 }

18}

And now, if we run php artisan test again:

1 

2 FAIL Tests\Unit\ExampleTest

3 that true is true

4 

5 FAIL Tests\Feature\ExampleTest

6 the application returns a successful response

7 

8---

9 

10 Tests\Unit\ExampleTest > that true is true

11Failed asserting that false is true.

12 

13at tests/Unit/ExampleTest.php:16

14 12▕ * @return void

15 13▕ */

16 14▕ public function test_that_true_is_true()

17 15▕ {

18 16▕ $this->assertTrue(false);

19 17▕ }

20 18▕ }

21 19▕

22 

23 Tests\Feature\ExampleTest > the application returns a successful response

24Expected response status code [200] but received 404.

25Failed asserting that 200 is identical to 404.

26 

27at tests/Feature/ExampleTest.php:19

28 15▕ public function test_the_application_returns_a_successful_response()

29 16▕ {

30 17▕ $response = $this->get('/non-existing-url');

31 18▕

32 19▕ $response->assertStatus(200);

33 20▕ }

34 21▕ }

35 22▕

36 

37 

38Tests: 2 failed

39Time: 0.11s

As you can see, there are two statements marked as FAIL, with explanations below and arrows to the exact test line that failed the assertion. So this is how the errors are shown. Convenient, isn’t it?


Simple Real-Life Example: Registration Form

Let’s get more practical and look at a real-life example. Imagine that you have a form, and you need to test various cases: check if it fails if filled with invalid data, check if it succeeds with the correct input, etc.

Did you know that the official Laravel Breeze starter kit comes with the feature tests inside? So, let’s take a look at a few examples from there:

tests/Feature/RegistrationTest.php

1use App\Providers\RouteServiceProvider;

2use Illuminate\Foundation\Testing\RefreshDatabase;

3use Tests\TestCase;

4 

5class RegistrationTest extends TestCase

6{

7 use RefreshDatabase;

8 

9 public function test_registration_screen_can_be_rendered()

10 {

11 $response = $this->get('/register');

12 

13 $response->assertStatus(200);

14 }

15 

16 public function test_new_users_can_register()

17 {

18 $response = $this->post('/register', [

19 'name' => 'Test User',

20 'email' => 'test@example.com',

21 'password' => 'password',

22 'password_confirmation' => 'password',

23 ]);

24 

25 $this->assertAuthenticated();

26 $response->assertRedirect(RouteServiceProvider::HOME);

27 }

28}

Here we have two tests in one class, as they are both related to the registration form: one is checking if the form is loaded correctly, and another one checks if the submission works well.

We get familiar with two other methods of checking the result, two more assertions: $this->assertAuthenticated() and $response->assertRedirect(). You can check all the available assertions in the official documentation of PHPUnit and Laravel Response. Keep in mind that some general assertions happen on $this object, while others check the specific $response from the route call.

Another important thing is the use RefreshDatabase; statement, with the trait, included above the class. It is needed when your test actions may affect the database, like in this example, registration adds a new entry in the users database table. For that, you would need to create a separate testing database that would be refreshed with php artisan migrate:fresh, every time the tests are executed.

You have two options: physically create a separate database, or use an in-memory SQLite database. It is both configured in the file phpunit.xml that comes by default with Laravel. Specifically, you need this part:

1<php>

2 <env name="APP_ENV" value="testing"/>

3 <env name="BCRYPT_ROUNDS" value="4"/>

4 <env name="CACHE_DRIVER" value="array"/>

5 <!-- <env name="DB_CONNECTION" value="sqlite"/> -->

6 <!-- <env name="DB_DATABASE" value=":memory:"/> -->

7 <env name="MAIL_MAILER" value="array"/>

8 <env name="QUEUE_CONNECTION" value="sync"/>

9 <env name="SESSION_DRIVER" value="array"/>

10 <env name="TELESCOPE_ENABLED" value="false"/>

11</php>

See the DB_CONNECTION and DB_DATABASE which are commented out? If you have SQLite on your server, the easiest action is to just uncomment those lines, and your tests will run on that in-memory database.

In this test, we assert that the user is authenticated successfully and is redirected to the correct homepage, but we can also test the actual data in the database.

In addition to this code:

1$this->assertAuthenticated();

2$response->assertRedirect(RouteServiceProvider::HOME);

We can also use Database Testing assertions and do something like this:

1$this->assertDatabaseCount('users', 1);

2 

3// Or...

4$this->assertDatabaseHas('users', [

5 'email' => 'test@example.com',

6]);


Another Real-Life Example: Login Form

Let’s take a look at one more test from Laravel Breeze.

tests/Feature/AuthenticationTest.php:

1class AuthenticationTest extends TestCase

2{

3 use RefreshDatabase;

4 

5 public function test_login_screen_can_be_rendered()

6 {

7 $response = $this->get('/login');

8 

9 $response->assertStatus(200);

10 }

11 

12 public function test_users_can_authenticate_using_the_login_screen()

13 {

14 $user = User::factory()->create();

15 

16 $response = $this->post('/login', [

17 'email' => $user->email,

18 'password' => 'password',

19 ]);

20 

21 $this->assertAuthenticated();

22 $response->assertRedirect(RouteServiceProvider::HOME);

23 }

24 

25 public function test_users_can_not_authenticate_with_invalid_password()

26 {

27 $user = User::factory()->create();

28 

29 $this->post('/login', [

30 'email' => $user->email,

31 'password' => 'wrong-password',

32 ]);

33 

34 $this->assertGuest();

35 }

36}

This is about the login form. The logic is similar to the registration, right? But three methods instead of two, so this is an example of testing both good and bad scenarios. So, the common logic is that you should test both cases: when things go well and when they fail.

Also, what you see in this test is the usage of Database Factories: Laravel creates a fake user (again, on your refreshed testing database) and then tries to log in, with correct or incorrect credentials.

Again, Laravel generates the default factory with fake data for the User model, out of the box.

database/factories/UserFactory.php:

1class UserFactory extends Factory

2{

3 public function definition()

4 {

5 return [

6 'name' => $this->faker->name(),

7 'email' => $this->faker->unique()->safeEmail(),

8 'email_verified_at' => now(),

9 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password

10 'remember_token' => Str::random(10),

11 ];

12 }

13}

See, how many things are prepared by Laravel itself, so it would be easy for us to start testing?

So, if we run php artisan test after installing Laravel Breeze, we should see something like this:

1 PASS Tests\Unit\ExampleTest

2 that true is true

3 

4 PASS Tests\Feature\Auth\AuthenticationTest

5 login screen can be rendered

6 users can authenticate using the login screen

7 users can not authenticate with invalid password

8 

9 PASS Tests\Feature\Auth\EmailVerificationTest

10 email verification screen can be rendered

11 email can be verified

12 email is not verified with invalid hash

13 

14 PASS Tests\Feature\Auth\PasswordConfirmationTest

15 confirm password screen can be rendered

16 password can be confirmed

17 password is not confirmed with invalid password

18 

19 PASS Tests\Feature\Auth\PasswordResetTest

20 reset password link screen can be rendered

21 reset password link can be requested

22 reset password screen can be rendered

23 password can be reset with valid token

24 

25 PASS Tests\Feature\Auth\RegistrationTest

26 registration screen can be rendered

27 new users can register

28 

29 PASS Tests\Feature\ExampleTest

30 the application returns a successful response

31 

32Tests: 17 passed

33Time: 0.61s


Feature Tests VS Unit Tests VS Others

You’ve seen the tests/Feature and tests/Unit subfolders. What is the difference between them? The answer is a little “philosophical”.

Globally, outside of Laravel/PHP ecosystem, there are different kinds of automated tests. You can find such terms as:

  • Unit tests
  • Feature tests
  • Integration tests
  • Functional tests
  • End-to-end tests
  • Acceptance tests
  • Smoke tests
  • etc.

It sounds complicated, and the actual differences between those test types sometimes are blurred. That’s why Laravel simplified all those confusing terms and grouped them into two: unit/feature.

In simple words, feature tests try to run the actual features of your applications: get the URL, call the API, mimic the exact behavior like filling in the form. Feature tests usually execute the same or similar thing as any project user would do, manually, in real life.

Unit tests have two meanings. Generally, you may find that any automated tests are called “unit tests”, and the whole process may be called “unit testing”. But in the context of feature vs unit, this process is about testing a specific non-public unit of your code, in isolation. For example, you have some Laravel class with a method that calculates something, like the total price of the order with parameters. So, your unit test would assert if the correct results are returned by that method (unit of code), with different parameters.

To generate a unit test, you need to add a flag:

1php artisan make:test OrderPriceTest --unit

The generated code is the same as the default unit test from Laravel:

1class OrderPriceTest extends TestCase

2{

3 public function test_example()

4 {

5 $this->assertTrue(true);

6 }

7}

As you can see, there’s no RefreshDatabase, and that’s one of the most common definitions of a unit test: it doesn’t touch the database, it works like a “black box”, in isolation from the running application.

Trying to mimic the example I mentioned earlier, let’s imagine we have a service class OrderPrice.

app/Services/OrderPriceService.php:

1class OrderPriceService

2{

3 public function calculatePrice($productId, $quantity, $tax = 0.0)

4 {

5 // Some kind of calculation logic

6 }

7}

Then, the unit test could look something like this:

1class OrderPriceTest extends TestCase

2{

3 public function test_single_product_no_taxes()

4 {

5 $product = Product::factory()->create(); // generate a fake product

6 $price = (new OrderPriceService())->calculatePrice($product->id, 1);

7 $this->assertEquals(1, $price);

8 }

9 

10 public function test_single_product_with_taxes()

11 {

12 $price = (new OrderPriceService())->calculatePrice($product->id, 1, 20);

13 $this->assertEquals(1.2, $price);

14 }

15 

16 // More cases with more parameters

17}

In my personal experience with Laravel projects, the absolute majority of the tests are Feature tests, not Unit tests. First, you need to test if your application works, the way how real people would use it.

Next, if you have special calculations or logic that you can define as a unit, with parameters, you may create unit tests specifically for that.

Sometimes, writing tests requires changing the code itself, and refactoring it to be more “testable”: separating the units into special classes or methods.


When/How To Run Tests?

What is the actual usage of that php artisan test, when you should run that?

There are different approaches, depending on your company workflow, but typically, you need to make sure that all tests are “green” (meaning, no errors) before you push your latest code changes to the repository.

So, you work locally on your task, and when you feel like you’ve finished, you run tests to make sure you didn’t break anything. Remember, your code may cause bugs not only in your logic but also unintentionally break some other behavior in someone else’s code written a long time ago.

If we take it a step further, it’s possible to automate a lot of things. With various CI/CD tools, you can specify your tests to be executed whenever someone pushes the changes to a specific Git branch, or before merging the code into the production branch. The easiest workflow would be to use Github Actions, I have a separate video demonstrating it.


What Should You Test?

There are various opinions on how big your so-called “test coverage” should be: should you test every operation and every possible case on every page, or just limit your work to the most important parts.

Indeed, this is where I agree with people blaming automated testing for taking more time than bringing the actual benefits. That may happen if you write tests for every single detail. That said, it may be required by your project: the main question is “what is the price of the potential error”.

In other words, you need to prioritize your testing efforts with the question “What would happen if this code fails?” If your payment system has bugs, it will directly impact the business. Then, if your roles/permissions functionality is broken, then it’s a huge security issue.

I like how Matt Stauffer phrased it during one conference: “You need to test those things first, which, if they fail, would get you fired from your job”. Of course, it’s an exaggeration, but you get the idea: test the important things first. And then other functionality, if you have time for it.


PEST: New Popular Alternative to PHPUnit

All the examples above are based on the default Laravel testing tool: PHPUnit. But over the years other tools were appearing in the ecosystem, and one of the latest popular ones is PEST. Created by the official Laravel employee Nuno Maduro, it has the goal of simplifying the syntax, making it even quicker to write the code for tests.

Under the hood, it runs on top of PHPUnit, as an additional layer, just trying to minimize some default repeating parts of PHPUnit code.

Let’s take a look at an example. Remember the default Feature test class in Laravel? I will remind you:

1namespace Tests\Feature;

2 

3use Illuminate\Foundation\Testing\RefreshDatabase;

4use Tests\TestCase;

5 

6class ExampleTest extends TestCase

7{

8 public function test_the_application_returns_a_successful_response()

9 {

10 $response = $this->get('/');

11 

12 $response->assertStatus(200);

13 }

14}

Do you know how the same test would look with PEST?

1test('the application returns a successful response')->get('/')->assertStatus(200);

Yes, ONE line of code, and that’s it. So, the goal of PEST is to remove the overhead of:

  • Creating classes and methods for everything;
  • Extending TestCase;
  • Putting actions on separate lines – in PEST, you can chain them.

To generate a PEST test in Laravel, you need to specify an additional flag:

1php artisan make:test HomepageTest --pest

At the time of writing this article, PEST is quite popular among Laravel developers, but it’s your personal preference whether to use this extra tool and learn its syntax, in addition to a well-known PHPUnit.


So, that’s all you need to know about the basics of automated testing. From here, it’s your choice on what tests to create and how to run them in your projects.

For more information, refer to the official Laravel docs on testing.

Laravel News