콘텐츠 대표 이미지 - Laravel Dusk: 브라우저 기반 E2E 테스트의 모든 것! 🚀

Laravel Dusk: 브라우저 기반 E2E 테스트의 모든 것! 🚀

안녕, 친구들! 오늘은 정말 흥미진진한 주제로 찾아왔어. 바로 'Laravel Dusk'야! 😎 이 녀석, 브라우저 기반 E2E 테스트의 끝판왕이라고 할 수 있지. 우리 함께 Laravel Dusk의 세계로 빠져볼까? 🏊‍♂️

그런데 잠깐, Laravel Dusk가 뭐냐고? 걱정 마! 지금부터 아주 쉽고 재미있게 설명해줄게. 마치 네가 재능넷에서 새로운 재능을 배우는 것처럼 말이야. 그럼 출발~! 🚗💨

🔍 알고 가자! Laravel Dusk는 Laravel 프레임워크에서 제공하는 브라우저 자동화 및 테스팅 도구야. 실제 사용자처럼 웹 애플리케이션을 조작하고 테스트할 수 있게 해주는 강력한 녀석이지!

Laravel Dusk의 매력 포인트 💖

  • 실제 브라우저에서 테스트가 가능해! 👀
  • 자바스크립트, CSS 등 모든 요소를 포함한 테스트가 가능하지.
  • 복잡한 설정 없이 바로 사용할 수 있어. 간편하다고~
  • Laravel 프레임워크와 완벽한 통합! 찰떡궁합이야. 🍫

이제 Laravel Dusk가 뭔지 대충 감이 오지? 그럼 이제부터 본격적으로 파헤쳐볼게. 준비됐어? Let's go! 🏃‍♂️💨

Laravel Dusk 시작하기: 설치부터 첫 테스트까지 🛠️

자, 이제 Laravel Dusk를 실제로 사용해볼 차례야. 마치 재능넷에서 새로운 재능을 배우는 것처럼, 차근차근 따라와 봐!

1. Laravel Dusk 설치하기 📦

먼저, Laravel 프로젝트에 Dusk를 설치해야 해. 터미널을 열고 다음 명령어를 입력해봐:

composer require --dev laravel/dusk

이 명령어로 Dusk가 개발 환경에 설치될 거야. 그 다음, Dusk 설치 명령어를 실행해야 해:

php artisan dusk:install

이렇게 하면 Dusk가 필요한 모든 파일들을 생성하고 설정해줄 거야. 쉽지? 😉

2. 첫 번째 Dusk 테스트 만들기 🎨

이제 우리의 첫 Dusk 테스트를 만들어볼 거야. 다음 명령어를 사용해서 테스트 파일을 생성해보자:

php artisan dusk:make LoginTest

이 명령어는 tests/Browser/LoginTest.php 파일을 생성할 거야. 이제 이 파일을 열어서 우리의 첫 테스트를 작성해보자!

3. 테스트 코드 작성하기 ✍️

LoginTest.php 파일을 열어보면 이런 모양일 거야:


<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class LoginTest extends DuskTestCase
{
    /**
     * A Dusk test example.
     */
    public function testExample(): void
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->assertSee('Laravel');
        });
    }
}

이제 이 코드를 수정해서 실제 로그인 테스트를 만들어볼게:


public function testLogin(): void
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/login')
                ->type('email', 'test@example.com')
                ->type('password', 'password')
                ->press('Login')
                ->assertPathIs('/home');
    });
}

이 테스트는 다음과 같은 일을 해:

  1. 로그인 페이지를 방문해.
  2. 이메일과 비밀번호를 입력해.
  3. 'Login' 버튼을 클릭해.
  4. 로그인 후 '/home' 경로로 이동했는지 확인해.

정말 간단하지? 마치 실제 사용자가 하는 행동을 그대로 코드로 옮긴 것 같아!

4. 테스트 실행하기 🏃‍♂️

자, 이제 우리가 만든 테스트를 실행해볼 차례야. 터미널에서 다음 명령어를 입력해봐:

php artisan dusk

이 명령어를 실행하면, Laravel Dusk가 Chrome 브라우저를 열고 우리가 작성한 테스트를 실행할 거야. 마치 투명한 손이 브라우저를 조작하는 것 같아 보일 거야. 신기하지? 😲

🌟 Pro Tip: 테스트가 실패하면 Dusk는 자동으로 스크린샷을 찍어서 tests/Browser/screenshots 폴더에 저장해줘. 이걸로 문제를 쉽게 찾을 수 있지!

여기까지 따라왔다면, 축하해! 🎉 넌 이제 Laravel Dusk의 기본을 마스터한 거야. 하지만 이건 시작에 불과해. Dusk로는 더 많은 걸 할 수 있어. 계속해서 더 깊이 파고들어볼까?

Laravel Dusk의 고급 기능들 🚀

자, 이제 우리는 Laravel Dusk의 기본을 알았어. 하지만 Dusk는 이것보다 훨씬 더 강력해! 마치 재능넷에서 고급 재능을 배우는 것처럼, 이제 Dusk의 더 멋진 기능들을 살펴볼 거야. 준비됐어? 😎

1. 요소 선택과 조작 🖱️

Dusk는 웹 페이지의 요소를 쉽게 선택하고 조작할 수 있게 해줘. 예를 들어보자:


$browser->click('.submit-button')
        ->value('#email', 'test@example.com')
        ->check('terms')
        ->radio('size', 'large')
        ->select('country', 'KR')
        ->press('Submit');

이 코드는 다음과 같은 일을 해:

  • '.submit-button' 클래스를 가진 요소를 클릭해.
  • '#email' ID를 가진 입력 필드에 이메일을 입력해.
  • 'terms' 체크박스를 체크해.
  • 'size' 라디오 버튼 중 'large'를 선택해.
  • 'country' 드롭다운에서 'KR'을 선택해.
  • 'Submit' 버튼을 눌러.

와우! 이렇게 하면 정말 사용자가 직접 조작하는 것처럼 테스트할 수 있어!

2. 대기와 지연 ⏳

웹 애플리케이션을 테스트할 때 가장 어려운 점 중 하나는 비동기 작업을 다루는 거야. Dusk는 이런 상황을 위한 다양한 대기 메서드를 제공해:


$browser->waitFor('.selector')
        ->waitForText('Hello')
        ->waitForReload()
        ->pause(1000);

이 코드는:

  • '.selector'가 나타날 때까지 기다려.
  • 'Hello' 텍스트가 나타날 때까지 기다려.
  • 페이지가 리로드될 때까지 기다려.
  • 1초 동안 일시 정지해.

이렇게 하면 Ajax 요청이나 JavaScript 애니메이션 같은 비동기 작업을 안정적으로 테스트할 수 있어!

3. 데이터베이스 작업 🗃️

Dusk 테스트에서 데이터베이스를 사용하고 싶다면? 걱정 마, Dusk는 그것도 지원해!


use Laravel\Dusk\Browser;
use App\Models\User;

$this->browse(function (Browser $browser) {
    $user = User::factory()->create([
        'email' => 'test@example.com',
    ]);

    $browser->loginAs($user)
            ->visit('/profile')
            ->assertSee($user->name);
});

이 코드는:

  1. 새로운 사용자를 데이터베이스에 생성해.
  2. 그 사용자로 로그인해.
  3. 프로필 페이지를 방문해.
  4. 사용자의 이름이 페이지에 표시되는지 확인해.

이렇게 하면 실제 데이터를 사용한 엔드-투-엔드 테스트가 가능해져!

4. 여러 브라우저 사용하기 🖥️🖥️🖥️

Dusk의 또 다른 강력한 기능은 여러 브라우저를 동시에 사용할 수 있다는 거야. 이건 실시간 채팅이나 멀티플레이어 게임 같은 기능을 테스트할 때 정말 유용해!


$this->browse(function (Browser $first, Browser $second) {
    $first->loginAs(User::find(1))
          ->visit('/chat');

    $second->loginAs(User::find(2))
           ->visit('/chat');

    $first->type('#message', 'Hey there!')
          ->press('Send');

    $second->waitForText('Hey there!')
           ->assertSee('Hey there!');
});

이 코드는:

  1. 두 개의 브라우저 인스턴스를 생성해.
  2. 각각 다른 사용자로 로그인하고 채팅 페이지로 이동해.
  3. 첫 번째 브라우저에서 메시지를 보내.
  4. 두 번째 브라우저에서 그 메시지를 받았는지 확인해.

이렇게 하면 실제로 두 명의 사용자가 상호작용하는 것처럼 테스트할 수 있어! 정말 멋지지?

5. 페이지 객체 사용하기 📄

테스트 코드가 복잡해지면 관리하기 어려워질 수 있어. 이럴 때 페이지 객체를 사용하면 좋아! 페이지 객체는 특정 페이지의 요소와 동작을 캡슐화한 클래스야.


php artisan dusk:page Login

이 명령어로 LoginPage 클래스가 생성돼. 이제 이 클래스를 수정해보자:


<?php

namespace Tests\Browser\Pages;

use Laravel\Dusk\Browser;
use Laravel\Dusk\Page as BasePage;

class Login extends BasePage
{
    public function url()
    {
        return '/login';
    }

    public function assert(Browser $browser)
    {
        $browser->assertPathIs($this->url());
    }

    public function elements()
    {
        return [
            '@email' => 'input[name=email]',
            '@password' => 'input[name=password]',
            '@submit' => 'button[type=submit]',
        ];
    }

    public function login(Browser $browser, $email, $password)
    {
        $browser->type('@email', $email)
                ->type('@password', $password)
                ->click('@submit');
    }
}

이제 이 페이지 객체를 테스트에서 사용할 수 있어:


$this->browse(function (Browser $browser) {
    $browser->visit(new Login)
            ->login('test@example.com', 'password')
            ->assertPathIs('/home');
});

이렇게 하면 코드가 훨씬 깔끔해지고 재사용성도 높아져! 마치 재능넷에서 재능을 모듈화해서 관리하는 것처럼 말이야.

6. 스크린샷과 콘솔 로그 📸🖨️

Dusk는 테스트 중에 스크린샷을 찍거나 브라우저 콘솔 로그를 저장할 수 있어. 이건 디버깅할 때 정말 유용해!


$browser->screenshot('test_name')
        ->storeConsoleLog('console_log');

이 코드는:

  • 현재 페이지의 스크린샷을 찍어 'tests/Browser/screenshots' 폴더에 저장해.
  • 브라우저 콘솔 로그를 'tests/Browser/console' 폴더에 저장해.

이렇게 하면 테스트가 실패했을 때 무슨 일이 일어났는지 정확히 알 수 있어!

7. 커스텀 명령어 만들기 🛠️

자주 사용하는 동작이 있다면 커스텀 명령어로 만들 수 있어. 예를 들어, 로그인 과정을 커스텀 명령어로 만들어보자:


<?php

namespace Tests\Browser;

use Laravel\Dusk\Browser;

trait CustomCommands
{
    public function login(Browser $browser, $email = null, $password = null)
    {
        $browser->visit('/login')
                ->type('email', $email ?? 'test@example.com')
                ->type('password', $password ?? 'password')
                ->press('Login')
                ->assertPathIs('/home');

        return $browser;
    }
}

이제 이 커스텀 명령어를 테스트에서 사용할 수 있어:


use Tests\Browser\CustomCommands;

class ExampleTest extends DuskTestCase
{
    use CustomCommands;

    public function testSomething()
    {
        $this->browse(function (Browser $browser) {
            $browser->login()
                    ->assertSee('Welcome');
        });
    }
}

이렇게 하면 자주 사용하는 동작을 쉽게 재사용할 수 있어! 코드도 깔끔해지고, 생산성도 올라가지!

🚨 주의사항: Dusk 테스트는 실제 브라우저를 사용하기 때문에 일반 단위 테스트나 기능 테스트보다 실행 시간이 오래 걸릴 수 있어. 그래서 CI/CD 파이프라인에서는 신중하게 사용해야 해!

여기까지 Laravel Dusk의 고급 기능들을 살펴봤어. 이 기능들을 잘 활용하면 정말 강력한 E2E 테스트를 만들 수 있어! 마치 재능넷에서 고급 재능을 익힌 것처럼 말이야. 😉 다음 섹션에서는 Dusk를 실제 프로젝트에 적용하는 방법에 대해 더 자세히 알아볼 거야. 준비됐지?

실전! Laravel Dusk 프로젝트 적용하기 🏗️

자, 이제 우리는 Laravel Dusk의 기본부터 고급 기능까지 배웠어. 근데 이걸 실제 프로젝트에 어떻게 적용하면 좋을까? 마치 재능넷에서 배운 재능을 실제 프로젝트에 적용하는 것처럼 말이야. 함께 알아보자!

1. 테스트 계획 세우기 📝

먼저, 어떤 부분을 테스트할지 계획을 세워야 해. 보통 다음과 같은 부분을 테스트하면 좋아:

  • 사용자 인증 (로그인, 로그아웃, 회원가입)
  • 주요 기능 (예: 게시글 작성, 수정, 삭제)
  • 복잡한 사용자 인터랙션 (예: 드래그 앤 드롭, 무한 스크롤)
  • 결제 프로세스
  • 반응형 디자인

이렇게 계획을 세우면 테스트 작성이 훨씬 체계적으로 될 거야!

2. 기본 설정 확인하기 ⚙️

Dusk를 사용하기 전에 tests/DuskTestCase.php 파일을 확인해봐. 여기서 Dusk의 기본 설정을 조정할 수 있어.


use Facebook\WebDriver\Chrome\ChromeOptions;

protected function driver()
{
    $options = (new ChromeOptions)->addArguments([
        '--disable-gpu',
        '--headless',
        '--window-size=1920,1080',
    ]);

    return RemoteWebDriver::create(
        'http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
            ChromeOptions::CAPABILITY, $options
        )
    );
}

이 설정은 Dusk가 headless 모드(화면에 보이지 않는 모드)로 실행되게 해. CI/CD 환경에서 테스트를 실행할 때 유용해!

3. 데이터베이스 설정 🗄️

Dusk 테스트는 실제 데이터베이스를 사용해. 그래서 테스트용 데이터베이스를 따로 설정하는 게 좋아. .env.dusk.local 파일을 만들어서 테스트용 데이터베이스 설정을 해보자:


APP_ENV=testing
DB_CONNECTION=mysql
DB_DATABASE=dusk_testing

이렇게 하면 테스트할 때 실제 데이터베이스를 건드리지 않아도 돼!

4. 페이지 객체 활용하기 📄

앞서 배운 페이지 객체를 실제로 활용해보자. 예를 들어, 게시판 페이지를 테스트한다고 해보자:


<?php

namespace Tests\Browser\Pages;

use Laravel\Dusk\Browser;
use Laravel\Dusk\Page as BasePage;

class BoardPage extends BasePage
{
    public function url()
    {
        return '/board';
    }

    public function assert(Browser $browser)
    {
        $browser->assertPathIs($this->url());
    }

    public function elements()
    {
        return [
            '@create-post' => '#create-post-btn',
            '@post-title' => 'input[name=title]',
            '@post-content' => 'textarea[name=content]',
            '@submit-post' => '#submit-post-btn',
        ];
    }

    public function createPost(Browser $browser, $title, $content)
    {
        $browser->click('@create-post')
                ->type('@post-title', $title)
                ->type('@post-content', $content)
                ->click('@submit-post');
    }
}

이제 이 페이지 객체를 사용해서 테스트를 작성할 수 있어:


public function testCreatePost()
{
    $this->browse(function (Browser $browser) {
        $browser->visit(new BoardPage)
                ->createPost('Test Title', 'This is a test post content.')
                ->assertSee('Post created successfully');
    });
}

이렇게 하면 테스트 코드가 훨씬 읽기 쉬워지고 유지보수하기도 편해져!

5. 데이터 팩토리 사용하기 🏭

테스트에 필요한 데이터를 생성할 때는 Laravel의 팩토리를 사용하면 좋아. 예를 들어, 사용자와 게시글을 생성하는 팩토리를 만들어보자:


// database/factories/UserFactory.php
public function definition()
{
    return [
        'name' => $this->faker->name,
        'email' => $this->faker->unique()->safeEmail,
        'password' => bcrypt('password'),
    ];
}

// database/factories/PostFactory.php
public function definition()
{
    return [
        'title' => $this->faker->sentence,
        'content' => $this->faker->paragraph,
        'user_id' => User::factory(),
    ];
}

이제 이 팩토리를 테스트에서 사용할 수 있어:


public function testViewPost()
{
    $post = Post::factory()->create();

    $this->browse(function (Browser $browser) use ($post) {
        $browser->visit('/posts/' . $post->id)
                ->assertSee($post->title)
                ->assertSee($post->content);
    });
}

이렇게 하면 테스트에 필요한 데이터를 쉽고 빠르게 생성할 수 있어!

6. CI/CD 파이프라인에 통합하기 🔄

Dusk 테스트를 CI/CD 파이프라인에 통합하면 자동으로 테스트를 실행할 수 있어. 예를 들어, GitHub Actions를 사용한다면 이렇게 설정할 수 있어:


name: Laravel Dusk Tests

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  dusk-php:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Prepare The Environment
        run: cp .env.example .env
      - name: Create Database
        run: |
          sudo systemctl start mysql
          mysql --user="root" --password="root" -e "CREATE DATABASE laravel character set UTF8mb4 collate utf8mb4_bin;"
      - name: Install Composer Dependencies
        run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader
      - name: Generate Application  Key
        run: php artisan key:generate
      - name: Upgrade Chrome Driver
        run: php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1`
      - name: Start Chrome Driver
        run: ./vendor/laravel/dusk/bin/chromedriver-linux &
      - name: Run Laravel Server
        run: php artisan serve &
      - name: Run Dusk Tests
        env:
          APP_URL: "http://127.0.0.1:8000"
        run: php artisan dusk
      - name: Upload Screenshots
        if: failure()
        uses: actions/upload-artifact@v2
        with:
          name: screenshots
          path: tests/Browser/screenshots
      - name: Upload Console Logs
        if: failure()
        uses: actions/upload-artifact@v2
        with:
          name: console
          path: tests/Browser/console

이렇게 설정하면 GitHub에 push하거나 pull request를 생성할 때마다 자동으로 Dusk 테스트가 실행돼!

7. 성능 최적화 🚀

Dusk 테스트는 실제 브라우저를 사용하기 때문에 실행 시간이 오래 걸릴 수 있어. 다음과 같은 방법으로 성능을 최적화할 수 있어:

  • 헤드리스 모드 사용: 브라우저 UI를 렌더링하지 않아 더 빠르게 실행돼.
  • 테스트 병렬 실행: tests/DuskTestCase.php$useParallelTesting = true;를 설정해.
  • 불필요한 대기 시간 줄이기: waitFor(), pause() 등의 사용을 최소화해.
  • 데이터베이스 트랜잭션 사용: 각 테스트 후 데이터베이스를 초기화하는 대신 트랜잭션을 사용해.

8. 모바일 테스트 📱

반응형 웹사이트를 테스트하려면 모바일 환경을 시뮬레이션해야 해. Dusk에서는 이렇게 할 수 있어:


$browser->resize(375, 812) // iPhone X 해상도
        ->visit('/')
        ->assertSee('모바일 메뉴');

이렇게 하면 다양한 디바이스 크기에서 웹사이트가 어떻게 보이는지 테스트할 수 있어!

9. 보안 테스트 🔒

Dusk를 사용해 기본적인 보안 테스트도 할 수 있어. 예를 들어:


public function testUnauthorizedAccessPrevented()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/admin')
                ->assertPathIs('/login');
    });
}

이 테스트는 로그인하지 않은 사용자가 관리자 페이지에 접근하려고 할 때 로그인 페이지로 리다이렉트되는지 확인해.

10. 지속적인 업데이트와 유지보수 🔄

Laravel과 Dusk는 계속 업데이트되고 있어. 프로젝트의 의존성을 정기적으로 업데이트하고, 새로운 기능이나 변경사항을 테스트에 반영하는 것이 중요해.


composer update laravel/dusk

이 명령어로 Dusk를 최신 버전으로 업데이트할 수 있어!

💡 Pro Tip: 테스트 코드도 실제 애플리케이션 코드만큼 중요해. 테스트 코드의 품질을 유지하고, 필요에 따라 리팩토링하는 것을 잊지 마!

여기까지 Laravel Dusk를 실제 프로젝트에 적용하는 방법에 대해 알아봤어. 이 모든 걸 한 번에 적용하기는 어려울 수 있어. 하지만 하나씩 차근차근 적용해 나가다 보면, 어느새 튼튼하고 신뢰할 수 있는 테스트 슈트를 갖게 될 거야. 마치 재능넷에서 배운 재능을 하나씩 실전에 적용하는 것처럼 말이야! 😊

Laravel Dusk를 사용하면서 궁금한 점이 있거나 어려움을 겪는다면 언제든 물어봐. 함께 해결해 나가면서 더 나은 개발자로 성장할 수 있을 거야. 화이팅! 🚀

댓글 작성

이 글에 대한 여러분의 생각을 들려주세요

댓글 0