Codelab: Gemini ช่วยเร่งการพัฒนาการทดสอบ

1. บทนำ

Codelab นี้จะแนะนำหลักการของ Test driven Development ( TDD) ซึ่งคุณสามารถเขียนการทดสอบก่อนที่จะใช้โค้ด เราจะสร้างแอปเครื่องคิดเลขแบบง่ายโดยใช้ Ruby เพื่อแสดงวิธีการนี้

และยังจะได้เรียนรู้วิธีใช้ Gemini เป็นผู้ช่วยเขียนโค้ดด้วย Gemini จะช่วยเร่งวงจร TDD ด้วยการสร้างกรอบการทดสอบ แนะนำการติดตั้งโค้ด และแม้แต่ให้คำอธิบายเกี่ยวกับโค้ด

สุดท้าย คุณจะได้ดูวิธีทำให้แอปเครื่องคิดเลขใช้งานได้กับ Cloud Function ซึ่งเป็นแพลตฟอร์มแบบ Serverless ที่มีการจัดการครบวงจรของ Google และทำให้แอปเข้าถึงได้

2. ข้อกำหนดเบื้องต้น

  • โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
  • เว็บเบราว์เซอร์

สร้างโปรเจ็กต์

เปิดใช้ Gemini API

  • ไปที่ Gemini Marketplace เพื่อเปิดใช้ API คุณยังใช้ gcloud เพื่อเปิดใช้ API ได้ด้วยวิธีการต่อไปนี้
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  • ไปที่หน้า Gemini แล้วคลิก "เริ่มแชท"
  • สำคัญ: ทำตามขั้นตอนที่ 1 และ 2 ใน Codelab นี้เพื่อเริ่มต้นใช้งาน Gemini และเปิดใช้ Gemini ใน Cloud Shell IDE ตามลำดับ

เปิดใช้ Cloud Functions API

gcloud services enable cloudfunctions.googleapis.com --project PROJECT_ID

เปิดใช้งาน Cloud Shell

  • คุณจะใช้ Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานใน Google Cloud Console ซึ่งโหลดไว้ล่วงหน้าพร้อมติดตั้งภาษาที่จำเป็น คลิกเปิดใช้งาน Cloud Shell ที่มุมขวาบนจาก Cloud Console:

6757b2fb50ddcc2d.png

  • เมื่อเชื่อมต่อกับ Cloud Shell คุณควรเห็นว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list
  • เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้เกี่ยวกับโปรเจ็กต์ของคุณ
gcloud config list project
  • หากไม่ได้ตั้งค่าโปรเจ็กต์ไว้ ให้ใช้คำสั่งต่อไปนี้เพื่อตั้งค่าโปรเจ็กต์
gcloud config set project <YOUR_PROJECT_ID>

ดูคำสั่งและการใช้งาน gcloud ในเอกสารประกอบ

เปิดเครื่องมือแก้ไข

  • สำหรับ Codelab นี้ เราจะใช้เครื่องมือแก้ไขระบบคลาวด์ภายใน คลิกปุ่มเปิดเครื่องมือแก้ไขที่มุมขวาบนในหน้าต่าง Cloud Shell ระบบจะเปิด VSCode Editor ให้คุณ

e5a5e95d543db556.png

เพิ่มส่วนขยาย Ruby

  • ในเมนูด้านซ้าย ให้คลิกไอคอนส่วนขยาย 999939b067e1d0dc.png เขียน vscode ruby ในแถบค้นหา และติดตั้งส่วนขยาย VSCode Ruby

a6fd4e37b3d847d2.png

3. อุ่นเครื่องกับ Gemini

LLM เป็นแบบกำหนดไม่ได้ ดังนั้น ในขณะที่คุณลองใช้ข้อความแจ้งเหล่านี้ คำตอบที่คุณได้รับอาจดูแตกต่างจากที่แสดงในภาพหน้าจอที่แนบมาใน Codelab

ก่อนอื่น มาถาม Gemini ว่า TDD คืออะไร โปรดทำตามขั้นตอนต่อไปนี้เพื่อเริ่มสนทนากับ Gemini ใน Cloud Shell Editor เดียวกับที่เรามีอยู่

  • มองหาไอคอน Gemini 25fdcae4447d063c.png ทางด้านซ้ายของหน้า ซึ่งจะเปิดหน้าต่างแชทให้คุณทางด้านซ้าย
  • คุณสามารถเริ่มพิมพ์ในช่องข้อความที่เขียนว่า Enter a prompt here

5e09b0fb6a1b44dd.png

พรอมต์:

What is Test Driven Development?

คำตอบ:

Test-driven development (TDD) is a software development methodology that requires developers to write automated tests before writing any production code. This helps ensure the code is correct and meets the requirement.
....

ซึ่งจะให้ข้อมูลเบื้องต้นเกี่ยวกับ TDD และประโยชน์ของ TDD

ต่อไปเรามาถาม Gemini กันว่า Ruby คืออะไร

พรอมต์:

What is Ruby?

คำตอบ:

Ruby is a general-purpose, interpreted, object-oriented programming language. It is designed to be easy to read and write. Ruby is dynamically typed, meaning that the type of a variable is not declared and can change during execution.
....

ซึ่งจะอธิบายว่า Ruby คืออะไรและประโยชน์ของการใช้ภาษา Ruby คืออะไร

4. การตั้งค่าโปรเจ็กต์

เรามาเริ่มต้นด้วยการสร้างแอป Sinatra แบบง่ายๆ กัน

  • มาสร้างโฟลเดอร์เปล่ากัน คุณสามารถตั้งชื่อได้ตามต้องการ เราจะเรียกว่า gemini-tdd สำหรับ Codelab นี้ สร้างโฟลเดอร์ใน /home/<YOUR-USERNAME>/ ในเครื่องมือแก้ไขระบบคลาวด์ทางด้านซ้ายใต้แท็บ Explorer

d1d920b074cd7c79.png

  • มาเปิดโฟลเดอร์ที่เราเพิ่งสร้างขึ้นมากัน ที่เมนูด้านซ้ายสุด ให้คลิกไอคอน 1d080370a3ccad53.png คลิกไฟล์ -> เปิดโฟลเดอร์
  • มาสร้างไฟล์ Ruby ใหม่ในโฟลเดอร์รูทนี้ซึ่งจะเป็นจุดเริ่มต้นสำหรับแอปกัน คุณจะตั้งชื่อไฟล์อะไรก็ได้ตามต้องการ เราจะเรียกว่า app.rb ใน Codelab นี้ วันที่ 7beab8d21c59eee7.png
  • เพิ่ม Gemfile ลงในโฟลเดอร์รูทด้วย เราขอแนะนำให้คุณถาม Gemini เกี่ยวกับ Gemfile ด้วย
  • นอกจากนี้ เราจะสร้างไฟล์ app_test.rb เพื่อเขียนกรอบการทดสอบ

5. การใช้งานที่ขับเคลื่อนโดย Gemini

เรามาเริ่มต้นด้วยการให้บริบทแก่ Gemini เกี่ยวกับสิ่งที่เรากำลังจะทำ และขอให้ Gemini สร้างกรอบการทดสอบสำหรับสิ่งเดียวกัน คัดลอกพรอมต์ต่อไปนี้ในพรอมต์แชทของ Gemini

พรอมต์:

Answer as a software engineer with Ruby expertise. We want to build a Ruby calculator application with a test driven development approach. Let's start by writing some tests for the calculator app using minitest gem.

คำตอบ:

Here is a simple test for a calculator app that adds two numbers:
require "minitest/autorun"

describe "Calculator" do
  it "should add two numbers" do
    calculator = Calculator.new
    assert_equal 5, calculator.add(2, 3)
  end
end
This test uses the assert_equal method to verify that the result of the add method is correct. 
.....

ซึ่งจะให้ตัวอย่างกรอบการทดสอบสำหรับแอปเครื่องคิดเลข เช่น การบวกตัวเลข 2 ตัว และยังนำเข้าทรัพยากร Dependency minitest/autorun ที่จำเป็นสำหรับการทดสอบด้วย ลองคัดลอกเนื้อหาไปที่ app_test.rb กัน มาลองทำการทดสอบตอนนี้ เนื่องจากเราไม่ได้เขียนโค้ดไว้ จึงจะล้มเหลวอย่างแน่นอน

มาถาม Gemini เกี่ยวกับวิธีทำการทดสอบกัน

พรอมต์:

How do we run the tests written in app_test.rb using ruby command?

คำตอบ:

To run the tests written in app_test.rb using the ruby command, you can use the following steps:
1.Make sure that you are in the same directory as the app_test.rb file.
2.Open a terminal window.
3.Type the following command:
ruby app_test.rb
This will run all of the tests in the app_test.rb file and report the results.

เรามาทำการทดสอบกันเลย คลิกขวาที่ app_test.rb ในแท็บ Explorer และคลิก "เปิดในเทอร์มินัลแบบผสานรวม"

66b4bb9598c1feca.png

ตรวจสอบว่าคุณอยู่ในโฟลเดอร์เดียวกับไฟล์ app_test.rb หากไม่ได้ใช้คำสั่ง cd เพื่อไปที่นั่น จากนั้นเรียกใช้คำสั่งที่ Gemini ส่งกลับมา

ruby app_test.rb

คุณจะพบข้อผิดพลาดต่อไปนี้

NameError: uninitialized constant Calculator

มาถาม Gemini วิธีแก้ไขจากเครื่องมือแก้ไขโดยตรงกัน คลิกไอคอนแชทในแผงการนำทางของตัวแก้ไข Cloud Shell แล้วถามจากข้อความแจ้งด้านล่าง

พรอมต์:

NameError: uninitialized constant Calculator. Give me Calculator class code.

คำตอบ:

The error you are getting is because you have not defined the Calculator class. You need to define the Calculator class before you can use it in your tests.
Here is the code for the Calculator class:
Class Calculator
  def add(a, b)
    a + b
  end
end
Once you have defined the Calculator class, you can run the tests again and they will pass.
.....

Gemini แจ้งว่าเราไม่มีคลาสชื่อ Calculator และจำเป็นต้องสร้างชั้นเรียน และยังให้รหัสสำหรับการสร้างชั้นเรียน Calculator แก่เราอีกด้วย ลองใช้โค้ดนี้กัน เปิด app.rb จากแท็บสำรวจแล้วคัดลอกโค้ดที่ Gemini ให้ไว้ ขณะแก้ไขเนื้อหาใน app.rb คุณอาจได้รับคําแนะนําจาก Gemini ว่าเป็นการเติมข้อความอัตโนมัติ คุณต้องกด tabหากต้องการยอมรับหรือ Esc หากไม่

เอาล่ะ มาลองทดสอบกันอีกครั้ง พิมพ์คำสั่งต่อไปนี้ในเทอร์มินัลที่ผสานรวม

ruby app_test.rb

แต่คุณยังคงพบข้อผิดพลาดเดิม "NameError: uninitialized constant Calculator" มาถาม Gemini วิธีแก้ไขกัน

6. TDD ซ้ำด้วย Gemini

พรอมต์:

I am still getting this error: "NameError: uninitialized constant Calculator".

คำตอบ:

The error you are getting is because you have not defined the Calculator class. You need to define the Calculator class before you can use it in your tests.
Here is the code for the Calculator class:
class Calculator
  def add(a, b)
    a + b
  end

  def subtract(a, b)
    a - b
  end

  def multiply(a, b)
    a * b
  end

  def divide(a, b)
    a / b
  end
end
....

ซึ่งให้คำตอบแก่เรา ซึ่งอาจจะเหมือนกับข้างต้นหรือไม่ก็ได้ เราจะบอก Gemini อย่างชัดแจ้งว่าเราได้กำหนดคลาสเครื่องคิดเลขไว้ใน app.rb

พรอมต์:

Calculator class is defined in app.rb already.

คำตอบ:

I see that the Calculator class is defined in the app.rb file. However, you are getting the NameError error because you are trying to use the Calculator class in the app_test.rb file without requiring the app.rb file.
To fix this, you need to add the following line to the top of the app_test.rb file:
require_relative "app"

เราได้รับคำตอบจาก Gemini ให้นำเข้า app.rb ที่เรากำหนดคลาสเครื่องคิดเลขไว้ บางครั้งคุณอาจต้องพูดคำสั่งซ้ำๆ อีก 2-3 ครั้งเพื่อให้ได้คำตอบที่เหมาะสม และเมื่อเข้าใจแล้ว ก็จะทำให้ดีขึ้นได้ โปรดทราบว่าคุณอาจเห็นข้อความ ต้องใช้ "./app" แทน ซึ่งเป็นคำตอบจาก Gemini เพิ่มข้อมูลโค้ดนี้ไปยัง app.rb ใน app_test.rb แล้วทำการทดสอบเดิมอีกครั้ง

โปรดตรวจสอบว่า app_test.rb มีลักษณะดังนี้

require "minitest/autorun"
require "./app"

describe "Calculator" do
  it "should add two numbers" do
    calculator = Calculator.new
    assert_equal 5, calculator.add(2, 3)
  end
end

เรียกใช้คำสั่งด้านล่างจาก Cloud Shell Terminal ในโฟลเดอร์โปรเจ็กต์

ruby app_test.rb

หากทุกอย่างเป็นไปด้วยดี การทดสอบก็ควรจะผ่าน เราจึงพัฒนาแอป Ruby ที่เรียบง่ายมากๆ โดยใช้แนวทางแบบ TDD และอาศัยความช่วยเหลือจาก Gemini คำตอบของพรอมต์อาจไม่ได้เหมือนกันทุกครั้ง ซึ่งเป็นไปตามลักษณะของโมเดล LLM คุณอาจได้รับการดำเนินการต่างๆ ของเครื่องคิดเลขเพิ่มขึ้นจาก Gemini แต่โดยรวมแล้วกระบวนการเดียวกันที่เราเพิ่งทำตามไปก็น่าจะใช้งานได้

7. ทำให้แอปใช้งานได้กับ Cloud Functions

ตอนนี้เราจะขอให้ Gemini ทำให้ฟีเจอร์นี้ใช้งานได้กับ Cloud Function

พรอมต์:

Let's deploy this app to Cloud Functions

คำตอบ:

To deploy your app to Cloud Functions, you can use the following steps:
1.Create a new Cloud Functions project.
2.Create a new Cloud Function.
3.Set the trigger for the Cloud Function to be an HTTP request.
4.Set the entry point for the Cloud Function to be the app method in the app.rb file.
5.Deploy the Cloud Function.
Once you have deployed the Cloud Function, you can test it by sending an HTTP request to the function's URL. 
....

Gemini จะอธิบายวิธีติดตั้งใช้งานด้วยตนเองโดยใช้ UI ของ Cloud Functions แต่ฉันไม่อยากทำแบบนั้น ลองขอให้ Gemini ออกคำสั่ง gcloud ที่ฉันเรียกใช้จากเทอร์มินัลที่ผสานรวมได้เลย

พรอมต์:

How do I deploy this app to Cloud Functions gen2 using the gcloud command?

คำตอบ:

...
Here are the specific commands you can use to deploy your app to Cloud Functions using the gcloud command:

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app

This command will create a new Cloud Function called calculator that is triggered by an HTTP request and uses the app method in the app.rb file as the entry point.

Once the Cloud Function is deployed, you can test it by sending an HTTP request to the function's URL. For example, you can use the following command to send a request to the function:

curl -X POST -H "Content-Type: application/json" -d '{"a": 2, "b": 3}' https://REGION-PROJECT_ID.cloudfunctions.net/calculator

มาเรียกใช้คำสั่ง gcloud ที่ได้รับจาก Gemini ในเทอร์มินัลกัน

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app

คุณจะพบข้อผิดพลาดต่อไปนี้

"ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Could not find Gemfile.lock file in your app. Please make sure your bundle is up to date before deploying.; Error ID: 7916f05c"

รับความช่วยเหลือจาก Gemini เพื่อแก้ไขข้อผิดพลาดกัน

พรอมต์:

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Could not find Gemfile.lock file in your app. Please make sure your bundle is up to date before deploying.; Error ID: 7916f05c

คำตอบ:

It looks like you're trying to deploy a function to Cloud Functions, but you don't have a Gemfile.lock file in your app. To fix this, run the following command in your app directory:
bundle install
This will create a Gemfile.lock file that lists all of the gems that your app uses.
...

เรียกใช้ bundle install ในเทอร์มินัลซึ่งจะสร้าง Gemfile.lock หลังจากเรียกใช้คำสั่ง ให้ตรวจสอบแท็บสำรวจ คุณควรเห็น Gemfile.lock

ลองทำให้ Cloud Functions ใช้งานได้อีกครั้ง เรียกใช้คำสั่ง Deploy เดียวกันในเทอร์มินัล:

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app

คุณจะพบข้อผิดพลาดอื่นต่อไปนี้

"ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: unable to execute functions-framework-ruby; please ensure a recent version of the functions_framework gem is in your Gemfile; Error ID: 89ae7dda"

8. เฟรมเวิร์กฟังก์ชันสำหรับ Ruby

ลองถาม Gemini เกี่ยวกับข้อผิดพลาดกัน

พรอมต์:

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: unable to execute functions-framework-ruby; please ensure a recent version of the functions_framework gem is in your Gemfile; Error ID: 89ae7dda

คำตอบ:

It looks like you're trying to deploy a function to Cloud Functions, but the build is failing because the functions_framework gem is not in your Gemfile. To fix this, add the following line to your Gemfile:

gem "functions_framework"

Then, run the following command to install the gem:

bundle install

Once the gem is installed, you can try deploying your function again.
....

พูดง่ายๆ ก็คือ แอปของเราไม่มีพระราชการทำงานของฟังก์ชัน_เฟรมเวิร์ก มาเพิ่มบรรทัดนี้ใน Gemfile กัน

gem "functions_framework"

ต่อไปให้เรียกใช้ bundle install ในเทอร์มินัล คุณอาจไม่พบข้อผิดพลาดที่ระบุว่า "ไม่มีทรัพยากรส่วนกลางที่ชัดแจ้งใน Gemfile" ที่ใช้เวลาเพียง 2 นาที หากพบปัญหานี้ โปรดตรวจสอบว่ามีบรรทัดต่อไปนี้เป็นบรรทัดแรกของ Gemfile

source "https://rubygems.org"

จากนั้นเรียกใช้ bundle install จากเครื่องชำระเงินอีกครั้ง ทีนี้ลองเรียกใช้คำสั่งติดตั้งใช้งานอีกครั้ง

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID

โดยจะพบข้อผิดพลาดต่อไปนี้

"ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: failed to verify function target "app" in source "app.rb": Undefined function: "app"; Error ID: e12ab0f9"

เพื่อแก้ไขปัญหานี้ เรามาลองใช้ฟีเจอร์ Generate Code ของ Gemini กัน เราจะเปิด app.rb จากแท็บ Explorer ซึ่งเรามีโค้ดของแอปเครื่องคิดเลขอยู่แล้ว ใน app.rb ในบรรทัดแรก ให้เริ่มพิมพ์ FunctionsFramework แล้วพิมพ์ "." คุณจะเห็นคำแนะนำเป็นข้อความสีเทา :

9e17476a4a586433.png

กด Tab เพื่อยอมรับคำแนะนำ เมื่อคำขอดังกล่าวได้รับการยอมรับแล้ว คุณจะเห็นคำแนะนำเพิ่มเติมดังที่แสดงด้านล่าง

f3c35d1539789acc.png

กด Tab เพื่อยอมรับคำแนะนำเพิ่มเติม ดังนั้น app.rb ควรมีลักษณะดังนี้

( เปลี่ยนชื่อฟังก์ชันจาก add เป็น app )

require "functions_framework"

FunctionsFramework.http "app" do |request|
 a = request.params["a"].to_i
 b = request.params["b"].to_i
 Calculator.new.add(a, b)
end

class Calculator
 def add(a, b)
   a + b
 end
end

เราเพิ่งสร้างจุดแรกเข้าสำหรับแอป Cloud Functions และได้เรียนรู้วิธีใช้คำแนะนำโค้ดของ Gemini ในตัวแก้ไขด้วย ตอนนี้เรามาลองทำให้แอปใช้งานได้อีกครั้ง

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID

และหากทุกอย่างเป็นไปตามปกติ การทำให้ใช้งานได้ก็ควรจะสำเร็จ และคุณควรจะเห็น URL ที่โฮสต์แอปของคุณอยู่ เยี่ยมมาก เรามาแก้ไข app.rb กันสักเล็กน้อยเพื่อแสดงผลลัพธ์การเพิ่ม app.rb สุดท้ายควรมีลักษณะดังนี้

require "functions_framework"

FunctionsFramework.http "app" do |request|
 a = request.params["a"].to_i
 b = request.params["b"].to_i
 calculator = Calculator.new
 add = calculator.add(a, b)
 "Result: #{add}"
end

class Calculator
 def add(a, b)
   a + b
 end
end

9. การทดสอบแบบเอนด์ทูเอนด์

เปิด URL และส่งต่อพารามิเตอร์การค้นหา a และ b ดังที่แสดงด้านล่าง

https://[APP-URL]/?a=2&b=3

คุณควรเห็นการตอบกลับเป็น "Result: 5" มีการดำเนินการหลายอย่างที่เครื่องคิดเลขทำได้ คุณสามารถขยายการทำงานของแอปนี้เพื่อให้ใช้งานได้เช่นกันและรับความช่วยเหลือจาก Gemini ได้

10. บทสรุป

เราได้เห็นวิธีพัฒนาแอป Ruby ในปัจจุบันโดยใช้แนวทาง TDD ด้วยความช่วยเหลือจาก Gemini อย่างที่คุณสังเกตเห็น Gemini อาจให้ผลลัพธ์ที่แตกต่างออกไป แต่สามารถช่วยเร่งกระบวนการพัฒนาในภาษาที่คุณอาจไม่คุ้นเคยมากที่สุด และยังคงแสดงฟังก์ชันหรือตัวอย่างเพื่อให้คุณเรียนรู้ได้เร็วขึ้น

นักพัฒนาซอฟต์แวร์คนใดก็ตาม ( ไม่ว่าจะมีประสบการณ์การใช้งานหรือไม่ก็ตาม) สามารถรับความช่วยเหลือจาก Gemini สำหรับขั้นตอนการพัฒนาของตนได้ หากไม่ได้ทำการพัฒนา ก็ใช้ Gemini เพื่ออธิบายโค้ดที่มีอยู่ได้ โดยขอให้ Gemini สร้างการทดสอบสำหรับโค้ดที่มีอยู่ ซึ่งเป็นงานที่น่าเบื่อที่สุดสำหรับฉันอย่างน้อย 🙂

ขอให้สนุกกับการเขียนโค้ดด้วย Gemini