درس تطبيقي حول الترميز: Gemini لتسريع التطوير المستند إلى الاختبار

1. مقدمة

يقدم هذا الدرس التطبيقي حول الترميز مبادئ Test Driven Development ( TDD ) ، حيث تكتب الاختبارات قبل تنفيذ التعليمات البرمجية. سننشئ تطبيق حاسبة بسيطًا باستخدام Ruby يعرض هذا النهج.

ستتعلّم أيضًا كيفية استخدام Gemini كمساعدك في الترميز. سيساعد Gemini في تسريع وتيرة تطوير النموذج الرقمي من خلال إنشاء حالات اختبار واقتراح عمليات تنفيذ للرموز البرمجية وحتى تقديم تفسيرات لها.

وأخيرًا، ستتعرف على كيفية نشر تطبيق "الآلة الحاسبة" في Cloud Function، وهي منصة مُدارة بالكامل بدون خوادم من Google، ما يتيح لك الوصول إلى تطبيقك.

2. المتطلبات الأساسية

  • مشروع على Google Cloud مع تفعيل الفوترة
  • متصفح الويب

إنشاء مشروعك

تفعيل Gemini API

  • انتقِل إلى سوق Gemini لتفعيل واجهة برمجة التطبيقات. يمكنك أيضًا استخدام gcloud لتفعيل واجهة برمجة التطبيقات:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID

تفعيل Cloud Functions API

  • في Google Cloud Console، ضمن صفحة أداة اختيار المشاريع، اختَر مشروعًا على Google Cloud أو أنشئه.
  • انتقِل إلى صفحة Cloud Functions API لتفعيل واجهة برمجة التطبيقات. يمكنك أيضًا استخدام gcloud لتفعيل واجهة برمجة التطبيقات:
gcloud services enable cloudfunctions.googleapis.com --project PROJECT_ID

تفعيل Cloud Shell

  • ستستخدم Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في Google Cloud Console ويتم تحميلها مسبقًا باللغات المطلوبة المثبّتة. من Cloud Console، انقر على تفعيل Cloud Shell في أعلى يسار الصفحة:

6757b2fb50ddcc2d.png

  • بعد الربط بخدمة Cloud Shell، من المفترَض أن يظهر لك أنّه سبق أن تمت مصادقتك وأنّ المشروع مضبوط على رقم تعريف مشروعك. شغِّل الأمر التالي في Cloud Shell لتأكيد أنه تمت مصادقتك:
gcloud auth list
  • شغّل الأمر التالي في Cloud Shell للتأكد من معرفة الأمر gcloud بمشروعك:
gcloud config list project
  • إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبطه:
gcloud config set project <YOUR_PROJECT_ID>

يمكنك الرجوع إلى المستندات حول أوامر gcloud واستخدامها.

فتح "محرّر إعلانات Google"

  • سنستخدم هذا الدرس التطبيقي حول الترميز. في نافذة Cloud Shell، انقر على الزر Open editor (فتح المُحرِّر) في أعلى يسار الشاشة. سيؤدي هذا الإجراء إلى فتح أداة VSCode Editor لك.

e5a5e95d543db556.png

إدراج إضافة Ruby

  • في القائمة الجانبية اليمنى، انقر على رمز الإضافات 999939b067e1d0dc.png، واكتب vscode ruby في شريط البحث وثبِّت إضافة VSCode Ruby.

a6fd4e37b3d847d2.png

3- الاستعداد لـ Gemini

النماذج اللغوية الكبيرة غير حتمية. لذلك، أثناء تجربة هذه الطلبات، قد يبدو الرد الذي تتلقّاه مختلفًا عن الردود الواردة في لقطات الشاشة المرفقة في الدرس التطبيقي حول الترميز.

لنسأل Gemini أولاً عن ماهية TDD. لبدء التحدّث إلى Gemini في محرِّر Cloud Shell نفسه الذي نحن فيه، يُرجى اتّباع الخطوات التالية:

  • على يمين الصفحة، ابحث عن رمز 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 وفوائده.

لنسأل 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 لهذا الدرس التطبيقي حول الترميز. في محرّر السحابة الإلكترونية على يمين الصفحة ضمن علامة التبويب "Explorer" (المستكشف)، أنشئ مجلدًا ضمن /home/<YOUR-USERNAME>/

d1d920b074cd7c79.png

  • لنفتح المجلد الذي أنشأناه للتو. في القائمة الموجودة في أقصى اليمين، انقر على الرمز 1d080370a3ccad53.png، ثم انقر على ملف -> افتح المجلد.
  • لننشئ ملف Ruby جديدًا في المجلد الجذر هذا وسيكون بمثابة نقطة بداية للتطبيق، ويمكنك تسميته كما تشاء. سنطلق عليها app.rb في هذا الدرس التطبيقي حول الترميز. 7beab8d21c59eee7.png
  • ولنضيف أيضًا Gemfile في المجلد الجذر. سيكون من المفيد سؤال Gemini عن Gemfile أيضًا.
  • وسننشئ أيضًا ملف app_test.rb لكتابة حالات الاختبار.

5- التنفيذ بالاستناد إلى 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. 
.....

ستحصل على نموذج حالة اختبار لتطبيق "الآلة الحاسبة"، أي لإضافة رقمين. تم أيضًا استيراد التبعية المطلوبة 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 الذي تم فيه تحديد فئة "الآلة الحاسبة". وقد يتطلّب الأمر أحيانًا تكرارَين أو ثلاثة من الطلبات للحصول على الردّ الصحيح، ولكن عندما تتعلم الإجابة، ستتحسّن النتائج. يُرجى العِلم أنّك قد ترى أيضًا طلب "./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. ولن تكون الردود السريعة هي نفسها في كل الأوقات، وهذا بطبيعة الحال مع نماذج النماذج اللغوية الكبيرة. من المحتمل أن يُجري Gemini المزيد من العمليات على "الآلة الحاسبة"، ولكن من المفترَض أن تنجح العملية نفسها التي اتّبعناها للتو.

7. نشر التطبيق في دوال Cloud

لنطلب الآن من 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 كيفية نشر الميزة يدويًا باستخدام واجهة مستخدم 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 مرة أخرى. نفِّذ أمر النشر نفسه في الوحدة الطرفية:

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.
....

لذلك في الأساس، نفتقد function_framework gem في تطبيقنا. دعنا نمضي قدمًا ونضيف هذا السطر في Gemfile:

gem "functions_framework"

شغِّل الآن bundle install في الوحدة الطرفية. قد تظهر رسالة الخطأ "لا يوجد مورد عمومي صريح في Gemfile" . إذا واجهت ذلك، تأكَّد من ضبط السطر التالي في السطر الأول من 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 على النحو التالي:

( إعادة تسمية اسم الدالة من إضافة إلى تطبيق )

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.