Codelab: Gemini ускорит разработку через тестирование

1. Введение

В этом практическом занятии мы познакомимся с принципами разработки через тестирование (TDD), где тесты пишутся до реализации кода. Мы создадим простое приложение-калькулятор на Ruby, демонстрирующее этот подход.

Вы также научитесь использовать Gemini в качестве помощника в программировании. Gemini поможет ускорить цикл TDD, генерируя тестовые примеры, предлагая варианты реализации кода и даже предоставляя пояснения к коду.

Наконец, вы узнаете, как развернуть приложение-калькулятор в Cloud Functions, полностью управляемой бессерверной платформе Google, что сделает ваше приложение доступным.

2. Предварительные требования

  • Проект в Google Cloud с включенной функцией выставления счетов.
  • веб-браузер

Создайте свой проект

Включите API Gemini

  • Перейдите на Gemini Marketplace , чтобы включить API. Вы также можете использовать gcloud для включения API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID

Включите API облачных функций.

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 и их использовании обратитесь к документации .

Открытый редактор

  • Для этого практического занятия мы будем использовать встроенный облачный редактор. В окне облачной оболочки нажмите кнопку «Открыть редактор» в правом верхнем углу. Это откроет для вас редактор VSCode.

e5a5e95d543db556.png

Добавить расширение Ruby

  • В меню слева нажмите на значок расширений. 999939b067e1d0dc.png Введите в строку поиска vscode ruby и установите расширение VSCode Ruby.

a6fd4e37b3d847d2.png

3. Разминка для Близнецов

LLM-ы являются недетерминированными. Поэтому, во время выполнения этих заданий, полученные ответы могут отличаться от тех, что показаны на скриншотах, прикрепленных к коду.

Давайте сначала спросим у Gemini, что такое TDD. Чтобы начать общение с Gemini в том же редакторе Cloud Shell, где мы находимся, выполните следующие шаги:

  • В левой части страницы найдите значок Близнецов. 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 и его преимущества.

Теперь давайте спросим у Близнецов, что такое Рубин:

Быстрый:

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 . В облачном редакторе слева, во вкладке «Проводник», создайте папку в каталоге /home/<YOUR-USERNAME>/

d1d920b074cd7c79.png

  • Давайте откроем только что созданную папку. В самом левом меню нажмите на значок 1d080370a3ccad53.png , нажмите Файл -> Открыть папку.
  • Давайте создадим новый Ruby-файл в этой корневой папке, который будет служить отправной точкой для приложения. Вы можете назвать его как угодно. В этом примере мы назовем его app.rb 7beab8d21c59eee7.png
  • Давайте также добавим Gemfile в корневую папку. Будет неплохо также запросить информацию о Gemfile у Gemini.
  • Мы также создадим файл app_test.rb для написания тестовых примеров.

5. Реализация, основанная на принципе «Близнецов»

Теперь давайте начнем с того, что дадим 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 во вкладке «Проводник» и выберите «Открыть во встроенном терминале».

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. Итеративная разработка через тестирование с использованием 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, что у нас определен класс Calculator в файле 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, где определен класс Calculator. Иногда может потребоваться 2-3 итерации запросов, чтобы получить правильный ответ, но по мере того, как вы будете осваиваться, все будет становиться лучше. Обратите внимание, что в ответе от Gemini вы также можете видеть require "./app" . Давайте добавим это в app_test.rb в файле app.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 в папке проекта:

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 объясняет, как развернуть его вручную с помощью пользовательского интерфейса 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.
....

По сути, в нашем приложении отсутствует гем functions_framework. Давайте добавим эту строку в наш Gemfile:

gem "functions_framework"

Теперь выполните команду bundle install в терминале. Возможно, вы столкнетесь с ошибкой «В Gemfile отсутствует явный глобальный ресурс». Если вы столкнетесь с этой ошибкой, убедитесь, что в первой строке вашего Gemfile содержится следующее:

source "https://rubygems.org"

Затем снова выполните команду bundle install из терминала. Теперь давайте снова выполним команду `deploy`:

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 на вкладке «Проводник», где уже находится код приложения «Калькулятор». В файле 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!