nothingworksinc / ticketbeast

Back to the lesson videos:
https://course.testdrivenlaravel.com/lessons
552 stars 11 forks source link

My TicketBeast notes #97

Open sileence opened 5 years ago

sileence commented 5 years ago

Get the ball rolling

Focus on the value you want to deliver with your application.

Work backwards ⬇️

Choose most important thing your app needs to do?

Then start with the most simple test (of the most important feature):

Test structure

Tests are usually divided into 3 parts:

Direct model access

Your test code has direct access to the domain code in your app. This allows you to:

Programming by wishful thinking

Write the code you wished it existed and then use the failing tests to implement that code.

Model Factories

Factories allow us to keep our tests focused on the things that are actually important.

Other Tips

💡Store money as cents (instead of float points). 💡Look for opportunities to make your tests faster (i.e. by not migrating or talking to the database). 💡See a test failing for a reason you'd expect it to fail is a good way to know you've got your test right. ⚠️ Think harder, don't hope tests will give you all the info you need! (or detect all possible errors).

Purchasing Concert Tickets

Browser Testing vs Endpoint Testing

Browser testing: simulate the user's actions inside the browser.

✅ Simulate how a user would interact with the application. ✅ Gives complete confidence the app is working end-to-end. ⚠️ Slower ⚠️ Brittle

The other cons mentioned in the lesson (complex to setup, can't interact with code directly) are solved by Laravel Dusk. To make your Laravel Dusk Browser tests less brittle use dusk-* attributes instead of relying in CSS selectors.

Endpoint testing: simulates how the browser would interact with the server (instead of how the user would interact with our app), by making HTTP requests directly to an endpoint.

✅ Faster ✅ Interact with more stable data structures (won't break if aesthetic changes are made to the UI) ✅ Interacts directly with the code ⚠️ Untested gap between frontend and backend

What do I want from my tests:

How to start

Start with a simple test with a name similar to the class name, then add more details as you gain more insight of what you actually want to test.

Later on you can rename the first test method to make it more specific.

“One of the biggest benefits of working with a Test Driven Approach is that the tests give you a good place to play with the code and figure out exactly what you want to land in terms of design.“

Asserting Exceptions

Asserting exceptions with try/catch && fail instead of @expectedException gives you the opportunity to execute more assertions on the exception object itself.

Reduce duplication in your tests

To remove duplication in different test methods you can overwrite the setUp method to store common values as properties, replace bindings in the Laravel Container, etc. For example:

protected $paymentGateway;

protected function setUp()
{
    parent::setUp(); // <- important to preserve the setup performed by the parent classes.

    $this->paymentGateway = new FakePaymentGateway;
    // Additional common code here...
}

You can also create custom assertions or test helpers, for example:

    private function orderTickets($concert, $params)
    {
        $this->json('POST', "/concerts/{$concert->id}/orders", $params);
    }

    // Note: check the method (assertSessionHasErrors) available in the current versions of Laravel.
    private function assertValidationError($field)
    {
        $this->assertResponseStatus(422);
        $this->assertArrayHasKey($field, $this->decodeResponseJson());
    }

Additional Tips

💡 Make the tests folder match the folder structure of your application 💡 Hide Eloquent details from the controllers (Extract to new methods and unit test those methods).

Limiting Ticket Sales

💡 Include an assertion in your arrange test in order to verify that a precondition is met.

$order = $concert->orderTickets('jane@example.com', 5);
$this->assertSame(5, $concert->ticketsRemaining());

💡 When you explicitly update a column in another model, example:

$ticket->update([‘order_id’ => null])

You can use that opportunity to create an explicit and more readable method in that model, example:

$ticket->release().

You might also want to unit test that method.

💡 Sometimes you might want to add redundant test coverage in order to get more explicit error messages when the tests fail. However as a downside the test suite might be slower and this might increase the work to maintain the tests suite.

jassehomar commented 5 years ago

👍

On Mon, May 6, 2019 at 7:58 AM Duilio Palacios notifications@github.com wrote:

I'm rewatching this course and thought about sharing some of the notes I wrote in my notebook while watching it for the first time. Is this useful to anybody? If so please thumbs up (or thumbs down if it's not). I'm thinking about adding the rest in this same thread as I go through the course again.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/nothingworksinc/ticketbeast/issues/97#issuecomment-489536998, or mute the thread https://github.com/notifications/unsubscribe-auth/AD26OZN2X6ZM7PBJEUWEMTTPT7QJJANCNFSM4HK54F5A .

cbaconnier commented 5 years ago

Please, do not comment a thumb up, but add a reaction on @sileence comment instead. Subscribers like me don't want to get notified every time

fwartner commented 5 years ago

Agree with that. It’s kinda annoying.

Mit freundlichen Grüßen, Florian Wartner Am 6. Mai 2019, 13:06 +0200 schrieb Clément Baconnier notifications@github.com:

Please, do not comment a thumb up, but add a reaction on @sileence comment instead. Subscribers like me don't want to get notified every time — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

sileence commented 5 years ago

Sorry about that guys, I deleted my comment and since there's enough interest and activity here I will just continue editing the main text to add the rest of the notes as I go through the course!

partounian commented 4 years ago

Adding my notes onto this :)

Steps for creating functionality are:

(notes/details for steps are located below the steps)

  1. Bullet point wanted [high-level] features

  2. Create a Feature Test file for testing the first step(/feature?) needed for this feature (app/Test/Feature/ViewConcertListingTest.php)

  3. Write desired api (wishful programming) and run test to make sure it fails (optionally begin by adding the comments // Arrange // Act // Assert to make the test steps clear)

  4. With minimal code necessary, make the test pass [fixing it one error at a time]

  5. Create Unit Test (file)

  6. Write desired api (wishful programming) and run test to make sure it fails (optionally begin by adding the comments // Arrange // Act // Assert to make the test steps clear)

  7. With minimal code necessary, make the test pass [fixing it one error at a time]

  8. Refactor


Details for above steps

  1. Bullet point wanted [high-level] features
  1. Create a Feature Test file for testing the first step(/feature?) needed for this feature (app/Test/Feature/ViewConcertListingTest.php)
  1. Create Unit Test (file)

Notes to self:

WIP and I would appreciate any constructive criticism. :)

More useful resources/notes

Adam Wathan - Chasing "Perfect" (removing conditions and improving clarity) https://www.youtube.com/watch?v=5DVDewOReoY

Pt. 2 of above https://adamwathan.me/2015/09/03/pushing-polymorphism-to-the-database/

Refactoring with Collections & Null Objects (spiritual part 3) https://adamwathan.me/2016/05/19/refactoring-with-collections-and-null-objects/

Livewire https://www.youtube.com/watch?v=bllMmnCtgbk https://www.youtube.com/watch?v=y3TQq534dRM

Eloquent subqueries https://www.youtube.com/watch?v=IBUXXErAtuk

Adam Wathan API Drift https://adamwathan.me/2016/02/01/preventing-api-drift-with-contract-tests/