iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
DevOps

自動化測試大作戰系列 第 25

情境題—文章瀏覽與評論(二)

  • 分享至 

  • xImage
  •  

Medium 清新閱讀版連結

今天就讓我們依照前一天的情境題,來撰寫測試案例函數吧!

先讓我們規畫擬訂測試案例:

測試案例

  1. 當使用者瀏覽文章清單頁時:
    1. 使用者可看到所有文章清單,也就是【文章清單API】要能確實將資料庫內的文章資料,筆數不多不少地回應出來。
  2. 當使用者瀏覽單一文章頁時:
    1. 使用者可看到該文章資料,也就是【單一文章API】要能確實將指定ID之文章在資料庫內的資料回應出來,並包含所有欄位。
    2. 使用者可取得單一文章評論清單資料,也就是【單一文章評論清單API】要能確實將指定ID之文章在資料庫內的評論資料回應出來,並包含所有欄位。
  3. 當使用者對單一文章新增評論時
    1. 使用者可針對此單一文章新增評論資料,也就是【新增單一文章評論API】在接受請求後,需新增一筆資料到資料庫。
    2. 使用者新增評論後,再次呼叫該文章評論清單API時,其回應資料應有包含新增的評論資料。

話不多說,來寫 Code !

測試案例函數實作

  • tests/Feature/ArticleControllerTest.php

    <?php
    
    namespace Tests\Feature;
    
    use App\Models\Article;
    use App\Models\User;
    use Database\Seeders\ArticleSeeder;
    use Database\Seeders\UserSeeder;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Illuminate\Foundation\Testing\WithFaker;
    use Illuminate\Foundation\Testing\WithoutMiddleware;
    use Tests\TestCase;
    
    class ArticleControllerTest extends TestCase
    {
        use WithoutMiddleware;
        use WithFaker;
        use RefreshDatabase;
    
        public function setUp(): void
        {
            parent::setUp();
    
            // 建立通用測試資料
            $this->seed([
                UserSeeder::class,
                ArticleSeeder::class,
            ]);
        }
    
        public function testUserBrowseArticleList()
        {
            // 建立測試資料
            $articles = Article::all();
    
            // 執行測試行為:對【文章清單API】發出請求
            $response = $this->get(route('article.list'));
            $response->assertOk()
                ->assertJsonStructure([
                    'data' => [
                        '*' => [
                            'id',
                            'content',
                        ],
                    ],
                ]);
    
            $list = $response->json('data');
            $listExpected = $articles->toArray();
    
            // 驗證結果
            $this->assertJsonStringEqualsJsonString(json_encode($listExpected), json_encode($list));
            $this->assertCount($articles->count(), $list);
        }
    
        public function testUserBrowseOneArticle()
        {
            // 建立測試資料
            $article = Article::find(1);
    
            // 執行測試行為:對【單一文章API】發出請求
            $response = $this->get(route('article.one', ['id' => $article->id]));
            $response->assertOk()
                ->assertJson([
                    'data' => [
                        'id' => $article->id,
                        'content' => $article->content,
                    ],
                ]);
    
            $comments = $article->comments;
    
            $responseComments = $this->get(route('article.one.comments', ['id' => $article->id]));
    
            $list = $responseComments->json('data');
            $listExpected = $comments->toArray();
    
            // 驗證結果
            $this->assertJsonStringEqualsJsonString(json_encode($listExpected), json_encode($list));
            $responseComments->assertOk()
                ->assertJsonStructure([
                    'data' => [
                        '*' => [
                            'id',
                            'article_id',
                            'user_id',
                            'content',
                        ],
                    ],
                ]);
            $this->assertCount($comments->count(), $list);
        }
    
        public function testUserPostCommentOnOneArticle()
        {
            // 建立測試資料
            $user = User::first();
            $article = Article::find(1);
    
            $data = [
                'comment' => $this->faker->text,
            ];
    
            // 執行測試行為:對【新增單一文章評論API】發出請求
            $response = $this->be($user)->post(route('article.one.comments.store', ['id' => $article->id]), $data);
    
            $responseComments = $this->get(route('article.one.comments', ['id' => $article->id]));
            $responseCommentsList = $responseComments->json('data');
    
            $foundPostedComment = false;
    
            foreach ($responseCommentsList as $comment) {
                if ($comment['content'] === $data['comment']) {
                    $foundPostedComment = true;
                    break;
                }
            }
    
            // 驗證結果
            $response->assertOk();
            $this->assertDatabaseHas('comments', [
               'article_id' => $article->id,
               'user_id' => $user->id,
               'content' => $data['comment'],
            ]);
            $this->assertTrue($foundPostedComment);
        }
    }
    

    在以上程式碼中,我們實作了以下測試案例函數:

    • testUserBrowseArticleList()

      在這個測試案例函數中,我們呼叫了【文章清單API】,並確認回應是否成功,資料結構是否符合預期,且是否就是資料庫中的所有資料。

    • testUserBrowseOneArticle()

      在這個測試案例函數中,我們呼叫了【單一文章API】及【單一文章評論API】,並各自確認回應是否成功,資料結構是否符合預期,且是否就是資料庫中的所有資料。

    • testUserPostCommentOnOneArticle()
      在這個測試案例函數中,我們呼叫了【新增單一文章評論API】,並確認回應是否成功,資料結構是否符合預期,且資料庫中是否有新增對應資料。接著,呼叫【單一文章評論API】,看其回應之是否包含剛新增的評論資料。

    除此之外,我們在 setUp() 函數內呼叫了 2 個 Seeder,建立各測試案例函數都會用到的通用測試資料:

    • setUp()

      public function setUp(): void
      {
          parent::setUp();
      
          // 建立通用測試資料
          $this->seed([
              UserSeeder::class,
              ArticleSeeder::class,
          ]);
      }
      

    此外,我們使用了幾個測試相關 Traits 來協助我們執行測試:

    • WithoutMiddleware:略過 Middleware 層之運行
    • WithFaker:方便建立假資料
    • RefreshDatabase:重建測試資料庫之用

以上就是今天的練習,希望對大家有所幫助。

明天讓我們再探討另一個情境題!


上一篇
情境題—文章瀏覽與評論(一)
下一篇
情境題—會員註冊(一)
系列文
自動化測試大作戰31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言