Wprowadzenie do testowania za pomocą narzędzia Gemini Code Assist

1. Wprowadzenie

W tym module użyjesz Gemini Code Assist, opartej na AI usługi wspomagającej w Google Cloud, aby dodać testy do istniejącej aplikacji internetowej w Pythonie oraz znaleźć i naprawić błędy w tej aplikacji wykryte przez testy. Następnie użyjesz Code Assist do tworzenia testów nowych funkcji i generowania kodu, który przejdzie te testy i rozszerzy aplikację.

Co musisz zrobić...

  • Aby pobrać kod istniejącej aplikacji internetowej, użyjesz edytora Cloud Shell.
  • Użyjesz czatu Gemini Code Assist w edytorze Cloud Shell, aby zadawać ogólne pytania dotyczące Google Cloud.
  • Użyjesz wbudowanej pomocy w zakresie kodu Gemini Code Assist w edytorze Cloud Shell, aby wygenerować testy aplikacji, uruchomić je, znaleźć i naprawić błędy, a następnie rozszerzyć funkcjonalność aplikacji.

Czego się nauczysz...

  • Jak korzystać z Gemini Code Assist w przypadku różnych zadań programistycznych, takich jak generowanie testów i kodu.
  • Jak korzystać z Gemini Code Assist, aby dowiedzieć się więcej o Google Cloud.

Co będzie Ci potrzebne...

  • przeglądarki Chrome,
  • konto Gmail,
  • Projekt w chmurze z włączonymi płatnościami
  • Usługa Gemini Code Assist jest włączona w Twoim projekcie w Cloud

Ten moduł jest przeznaczony dla deweloperów na wszystkich poziomach zaawansowania, w tym dla początkujących. Chociaż przykładowa aplikacja jest napisana w języku Python, nie musisz znać tego języka, aby zrozumieć, co się dzieje. Skupimy się na zapoznaniu się z możliwościami Gemini Code Assist dla programistów.

2. Konfiguracja

Aby wykonać to ćwiczenie, musisz mieć projekt w Google Cloud z włączonym rozliczaniem. Teraz włączymy interfejs Gemini API w naszym projekcie Google Cloud. Wykonaj te czynności:

  1. Otwórz https://console.cloud.google.com i upewnij się, że masz wybrany projekt Google Cloud, w którym chcesz pracować w tym module. Kliknij ikonę Gemini w prawym górnym rogu.

GeminiBanner.png

  1. Po prawej stronie konsoli Cloud otworzy się okno Gemini w Cloud. Jeśli poniżej pojawi się przycisk Włącz, kliknij go. Jeśli nie widzisz przycisku Włącz, a zamiast niego widzisz interfejs czatu, oznacza to, że Gemini w Cloud jest już włączony w projekcie. Możesz przejść bezpośrednio do następnego kroku.

GeminiApiEnable.png

  1. Po włączeniu możesz przetestować Gemini, zadając mu kilka pytań. Wyświetli się kilka przykładowych zapytań, ale możesz też wpisać np. Co to jest Cloud Run?

GeminiChatWindow.png

Asystent do kodowania odpowie na Twoje pytanie. Aby zamknąć okno czatu Asystenta kodu, w prawym górnym rogu kliknij ikonę f68286b2b2ea5c0a.png.

Włączanie Gemini w edytorze Cloud Shell

Usługa Gemini Code Assist jest dostępna i działa podobnie w kilku popularnych środowiskach IDE. W tym ćwiczeniu będziesz używać edytora Google Cloud Shell, który działa w całości w przeglądarce. Musisz włączyć i skonfigurować Gemini w edytorze Cloud Shell. Poniżej znajdziesz instrukcje:

  1. Uruchom Cloud Shell, klikając ikonę pokazaną poniżej. Uruchomienie instancji Cloud Shell może potrwać kilka minut.

72dc3df7b007fcde.png

  1. Kliknij przycisk Edytor lub Otwórz edytor (w zależności od przypadku) i poczekaj, aż pojawi się edytor Cloud Shell. Jeśli widzisz przycisk Wypróbuj nowy edytor, kliknij go.

CloudShellEditor.png

  1. Na pasku stanu u dołu kliknij przycisk Cloud Code – zaloguj się, jak pokazano na ilustracji. Autoryzuj wtyczkę zgodnie z instrukcjami. Jeśli na pasku stanu widzisz „Cloud Code – brak projektu”, wybierz tę opcję, a następnie wybierz z listy projekt Google Cloud, z którym chcesz pracować.

CloudCodeSignIn.png

  1. Jeśli nie widzisz ikony Gemini na pasku stanu w prawym dolnym rogu, musisz włączyć ją w Cloud Code. Zanim to zrobisz, upewnij się, że Gemini (wcześniej Duet AI for Developers) jest włączony w IDE. W tym celu kliknij Rozszerzenie Cloud Code → Ustawienia, a następnie wpisz tekst Duet AI: włącz, jak pokazano poniżej. Sprawdź, czy pole wyboru jest zaznaczone. Zrestartuj IDE. Włącza to Gemini w Cloud Code, a na pasku stanu w IDE pojawi się Gemini.

EnableDuetAiSetting.png

  1. W prawym dolnym rogu kliknij przycisk Gemini, jak pokazano na ilustracji, i wybierz odpowiedni projekt w chmurze Google, w którym włączyliśmy interfejs Cloud AI Companion API.

GeminiSelectGoogleCloudProject.png

  1. Po wybraniu projektu w chmurze Google Cloud sprawdź, czy wyświetla się on w komunikacie o stanie Cloud Code na pasku stanu i czy po prawej stronie na pasku stanu masz włączoną usługę Gemini, jak pokazano poniżej:

GeminiEnabledStatusBar.png

Usługa Gemini Code Assist jest gotowa do użycia.

3. Pobieranie i sprawdzanie aplikacji

W oknie terminala uruchom polecenie, aby sklonować repozytorium z kodem początkowym, a następnie przejdź do nowego katalogu (jeśli okno terminala nie jest już otwarte, kliknij przycisk Terminal lub Otwórz terminal, aby go przywrócić):

git clone https://github.com/GoogleCloudPlatform/testing-with-duet-ai-codelab.git
cd testing-with-duet-ai-codelab

Otwórz plik main.py w edytorze, a potem otwórz okno rozmowa z Gemini, klikając ikonę czatu z Gemini po lewej stronie edytora. Okno Gemini Chat znajduje się w środowisku IDE i zawiera kod z tego środowiska, który służy jako kontekst rozmowy. Wpisz prompt Wyjaśnij to i wyświetl odpowiedź:

GeminiChatExplainThis.png

Możesz przewinąć to okno czatu, aby zobaczyć całą odpowiedź. Z wyjaśnienia wynika, że ten program można uruchomić lokalnie za pomocą polecenia python3 main.py w oknie terminala.

4. Uruchamianie lokalne

W razie potrzeby przejdź do katalogu repozytorium za pomocą polecenia cd ~/testing-with-duet-ai-codelab i w oknie terminala wpisz polecenie python3 main.py:

3bf558e9cea15375.png

Kliknij link http://127.0.0.1:8080, aby otworzyć nową kartę przeglądarki ze stroną główną aplikacji:

fb06f382a4c03e4c.png

Aplikacja jest uruchomiona „lokalnie”. Edytor Cloud Shell wykonał tu małą magię. Aplikacja działa w Cloud Shell, a nie na Twoim komputerze. Po kliknięciu linku otworzyła się karta nie z rzeczywistym adresem lokalnym http://127.0.0.1:8080, ale z serwerem proxy skonfigurowanym w tym celu przez Cloud Shell. Efekt jest taki sam, jakbyś uruchamiał(-a) go lokalnie.

Wypróbuj go. Wpisz 25 i naciśnij Konwertuj!

e1b9d5832f6d0058.png

Tak, 25 to XXV w cyfrach rzymskich. To wszystko.

Może sprawdź jeszcze kilka numerów. 25 działa, a co z 24?

37982e385e17baac.png

Być może zbyt pochopnie uznaliśmy, że wszystko jest w porządku. Czy XXIIII to prawidłowa konwersja liczby 24? Czy nie powinno być XXIV?

Można argumentować, że XXIIII jest prawidłowe, ale nie jest to forma, której ludzie zwykle oczekują. Nie jest to jednak błąd (wiele zegarów pokazuje cyfrę 4 jako IIII), więc zostawmy to na przyszłość.

A może spróbujesz liczb ujemnych? Zero? Nie można ich zapisać za pomocą cyfr rzymskich. Użytkownik nie otrzymuje żadnej odpowiedzi, co wygląda na błąd, który należy rozwiązać.

Testowanie pomaga wykrywać i eliminować błędy, a Gemini Code Assist może pomóc w pisaniu i używaniu testów.

5. Dodawanie testów

Wróć do okna Gemini Chat i zapytaj

How can I test the number_to_roman function?

Przeczytaj odpowiedź, która powinna zawierać omówienie modułów unittestpytest.

Możesz poprosić Gemini Code Assist o napisanie tych testów. Otwórz w edytorze plik calendar.py, w którym znajduje się kod konwersji, wróć do okna Gemini Chat i ponownie zapytaj:

How can I test the number_to_roman function?

Odpowiedź jest teraz bardziej szczegółowa, zawiera nawet moduł testu jednostkowego, który możesz skopiować lub wstawić do nowego pliku:

import unittest
import calendar

class NumberToRomanTest(unittest.TestCase):

    def test_convert_1(self):
        self.assertEqual(calendar.number_to_roman(1), "I")

    def test_convert_4(self):
        self.assertEqual(calendar.number_to_roman(4), "IV")

    def test_convert_9(self):
        self.assertEqual(calendar.number_to_roman(9), "IX")

    def test_convert_40(self):
        self.assertEqual(calendar.number_to_roman(40), "XL")

    def test_convert_90(self):
        self.assertEqual(calendar.number_to_roman(90), "XC")

    def test_convert_400(self):
        self.assertEqual(calendar.number_to_roman(400), "CD")

    def test_convert_900(self):
        self.assertEqual(calendar.number_to_roman(900), "CM")

    def test_convert_1990(self):
        self.assertEqual(calendar.number_to_roman(1990), "MCMXC")

    def test_convert_2023(self):
        self.assertEqual(calendar.number_to_roman(2023), "MMXXIII")

Może się on różnić od przykładu powyżej. Modele bazowe Gemini Code Assist są co jakiś czas aktualizowane, więc odpowiedzi nie zawsze będą takie same. Jeśli widzisz inny zestaw kodu, możesz kontynuować pracę z przykładami pokazanymi w tym laboratorium, kopiując kod, który tu widzisz, lub wypróbować alternatywną odpowiedź, którą teraz podaje Gemini Code Assist. Jeśli masz czas, możesz nawet wypróbować obie ścieżki. Gemini Code Assist to asystent kodowania, z którego możesz korzystać w dowolny sposób.

Kliknij dwukierunkową strzałkę w prawym górnym rogu okna Gemini Chat, aby utworzyć nowy plik zawierający kod testu jednostkowego, lub użyj IDE, aby utworzyć nowy plik i wkleić kod pokazany w tym ćwiczeniu. Aby zapisać plik, naciśnij CTRL-S lub CMD-S w tym oknie i nadaj mu nazwę calendar-unittest.py.

Wróć do terminala i naciśnij CTRL-C, aby zatrzymać serwer WWW, który został uruchomiony wcześniej, i uzyskać wiersz poleceń. Wpisz polecenie

python3 calendar-unittest.py

aby przeprowadzić nowe testy.

Brak danych wyjściowych. Nie tego się spodziewaliśmy. Czy wszystko przebiegło bez problemów? Chcesz mieć pewność. Wróć do odpowiedzi Gemini Code Assist, która zawierała kod testu. Pod kodem znajdowały się dodatkowe informacje o tym, jak uruchomić przypadek testowy:

run-unittest.png

Spróbuj uruchomić zalecane polecenie:

python -m unittest discover

Jeśli na Twoim komputerze polecenie python3 nie jest aliasem polecenia python, uruchom:

python3 -m unittest discover

Polecenie jest uruchamiane, ale zwraca wartość Ran 0 tests in 0.000s. Moduł zawiera kilka testów. Co się dzieje?

Chodzi o ostatnie słowo w poleceniu, czyli discover. Skąd pochodzi? Najwyraźniej Gemini Code Assist oczekiwał, że kod testu zostanie zapisany w pliku o nazwie discover lub discover.py, ale nie podał tej informacji. Plik został zapisany w calendar-unittest.py, więc spróbuj uruchomić to polecenie:

python3 -m unittest calendar-unittest

Zobaczysz teraz wiele danych wyjściowych, zaczynających się od czegoś takiego:

$ python3 -m unittest calendar-unittest
.F.FFFFFF
======================================================================
FAIL: test_convert_1990 (calendar-unittest.NumberToRomanTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/charles_engelke/testing-with-duet-ai-codelab/calendar-unittest.py", line 28, in test_convert_1990
    self.assertEqual(calendar.number_to_roman(1990), "MCMXC")
AssertionError: 'MDCCCCLXXXX' != 'MCMXC'
- MDCCCCLXXXX
+ MCMXC

W pierwszym wierszu wyświetla się okres dla każdego testu, który zakończył się powodzeniem, oraz symbol F dla każdego testu, który zakończył się niepowodzeniem. Większość testów kończy się niepowodzeniem. Następnie wyświetla listę poszczególnych testów, które się nie powiodły, pokazując oczekiwane i rzeczywiste dane wyjściowe. Nie jest do końca jasne, w jakiej kolejności przeprowadzono te testy. Była ona uporządkowana alfabetycznie według nazwy testu, a nie w kolejności, w jakiej testy występują w pliku. Najpierw pobiegł test_convert_1, potem test_convert_1990, potem test_convert_2023 i tak dalej. Tylko testy 12023 zostały zaliczone.

Gdy po raz pierwszy wypróbujesz ten kod, zauważysz, że przekształca on 24 na XXIIII, co nie jest do końca błędne, ale nie jest to typowa forma, w której IIII jest przekształcane na IV. Wszystkie testy, które się nie powiodły, dotyczyły podobnych przypadków. Gdy po raz pierwszy zauważono ten problem, zespół powiedział: „Nie jest to tak naprawdę błąd (wiele zegarów pokazuje 4 jako cyfrę rzymską IIII), więc zostawmy to na przyszłość”.

Możesz zmienić przypadki testowe, aby oczekiwać i akceptować odpowiedzi „nie do końca błędne”, które generuje kod, lub zaakceptować, że nadszedł czas na „przyszłe ulepszenie”. Następnym krokiem jest poprawienie kodu przy pomocy Gemini Code Assist, aby uzyskać bardziej akceptowalne odpowiedzi, których oczekują testy.

6. Ulepszanie kodu

Pamiętaj, że odpowiedzi takie jak XXIIII w przypadku 24 zamiast bardziej typowej odpowiedzi XXIV zostały uznane za „nie do końca błędne” i odłożone do przyszłego ulepszenia. Ta przyszłość jest już tu. Odpowiedzi, które „nie są do końca błędne”, nadal są irytujące.

Pierwsza zasada dotycząca powtarzających się cyfr w liczbach rzymskich jest następująca: jeśli masz 4 identyczne cyfry z rzędu, należy je zastąpić jedną z nich, po której następuje cyfra o jeden wyższa. Dlatego XXIIII należy zastąpić XXIV. Podobnie XXXX należy zmienić na XL, a CCCC na CD.

Zapytaj Gemini Code Assist, jak zmienić wartość zmiennej roman w ten sposób tuż przed zwróceniem jej przez funkcję number_to_roman:

If the final value of roman has IIII in it, that should be replaced by IV. Similarly XXXX should be replaced by XL, and CCCC should become CD. How can I make those changes?

Sugerujemy dodanie na końcu tego kodu:

6437c3fa2c5fabd1.png

Skopiuj lub wpisz te wiersze w edytorze, a potem sprawdź, co się stanie:

dcefa568cab82fb7.png

Gemini Code Assist dodał więcej wierszy, aby obsługiwać przypadki, które mogą wystąpić po dokonaniu pierwszego zestawu zamian. Na przykład liczba 19 zostanie przekształcona w XVIIII, następnie w XVIV, a na końcu w prawidłową postać XIX.

Jeśli Gemini Code Assist zaproponuje przydatne sugestie, naciśnij Tab, aby je zaakceptować, zapisać plik i ponownie uruchomić serwer WWW. W przeciwnym razie dodaj ręcznie wiersze pokazane w tym przykładzie i zapisz plik. Wypróbuj trudną konwersję: 1999:

a206999587fdc9.png

Zgadza się!

Ponownie uruchom testy. Wszystkie przechodzą!

Aplikacja internetowa wydaje się gotowa do wdrożenia w środowisku produkcyjnym.

7. Wdrożenie w Cloud Run

Cloud Run uruchomi za Ciebie skonteneryzowaną aplikację w internecie. W przypadku aplikacji napisanych przy użyciu popularnych platform, takich jak Flash, polecenie gcloud run deploy utworzy nawet kontener przed wdrożeniem. Uruchom polecenie:

gcloud run deploy

W terminalu. Gdy pojawi się pytanie o lokalizację kodu źródłowego, naciśnij Enter, aby zaakceptować sugerowaną lokalizację. Podobnie, gdy pojawi się prośba o podanie nazwy usługi, naciśnij Enter, aby zaakceptować sugestię.

Polecenie może się nie powieść, ponieważ gcloud nie może określić, którego projektu użyć. W takim przypadku uruchom to polecenie:

gcloud config set core/project <project-id>

gdzie jest zastąpione identyfikatorem projektu, który może być taki sam jak jego nazwa. Następnie uruchom ponownie polecenie gcloud run deploy.

  • Polecenie wyświetli informację, że niektóre interfejsy API są potrzebne, ale nie zostały jeszcze włączone. Wpisz „y”, aby włączyć te funkcje.
  • Gdy pojawi się prośba o wybranie regionu, wybierz ten, który Ci odpowiada. Wpisanie numeru odpowiadającego us-central1 jest bezpiecznym wyborem.
  • Gdy pojawi się pytanie, wpisz Y, aby kontynuować.
  • Chcesz zezwolić na nieuwierzytelnione wywołania tej usługi Cloud Run. Opcja uwierzytelniania używana przez Cloud Run jest odpowiednia dla programów wywołujących usługę. Ponieważ jest to witryna, nie będziesz używać uwierzytelniania.

Google Cloud utworzy kontener, wdroży go, przekieruje do niego ruch i ustawi zasady dostępu, a następnie wyświetli link do strony głównej:

94ba7d8d63a44afd.png

Możesz kliknąć ten link i uzyskać dostęp do aplikacji.

a2e51666dfd33a9f.png

Wpisz liczbę i naciśnij Enter. Gotowe!

5021535ac991a95c.png

Co?!

Działa na Twoim urządzeniu! Dlaczego to nie jest gotowe?

Dowiedz się więcej Zapytaj Gemini Code Assist:

Why am I getting an internal server error on cloud run?

4b24321251d6eddf.png

Gemini Code Assist może odczytać plik dziennika, który zawiera podobne informacje. Zapytajmy Gemini Code Assist, jak samodzielnie sprawdzić logi:

92d1855be73ef1d.png

Zrób to. Poszukaj wierszy z czerwonymi wskaźnikami błędów !!, jak poniżej:

9bed4f9ed82de21c.png

Następuje po tym wiele wierszy szczegółów dotyczących stosu wywołań, ale potem pojawia się ten komunikat:

47fc93be845f4e3f.png

Gdy otworzysz plik calendar.py, zobaczysz funkcję number_to_roman. Wiesz, że jest poprawny, bo działał na Twoim komputerze. Co może się różnić w Cloud Run?

Odpowiedź jest złożona. Python 3 zawiera standardowy moduł o nazwie calendar, podobnie jak plik calendar.py, w którym zdefiniowana jest funkcja number_to_roman. Gdy na komputerze lokalnym Python szukał modułu o nazwie calendar, najpierw przeszukiwał katalog aplikacji. Okazuje się, że Python w Cloud Run najpierw szukał standardowych modułów, importował je i nie znalazł funkcji number_to_roman.

Takie różnice w środowiskach są zawsze możliwe. Na szczęście, gdy aplikacja jest skonteneryzowana, zawiera w sobie swoje środowisko, więc gdziekolwiek ją uruchomisz, możesz oczekiwać takiego samego działania. Gdyby ta sama skonteneryzowana aplikacja, którą ma Cloud Run, była uruchomiona lokalnie, wystąpiłby ten sam problem.

Rozwiąż ten problem. Musisz zmienić nazwę lokalnego modułu kalendarza na taką, która nie jest też standardową nazwą modułu. Zmień nazwę pliku calendar.py na my_calendar.py, a następnie zmień wiersze import calendar w plikach main.py i calendar-unittest.py na import my_calendar. Na koniec zmień wiersz.

roman = calendar.number_to_roman(number)

do

roman = my_calendar.number_to_roman(number)

Wypróbuj go lokalnie, uruchom testy, a potem wdróż ponownie:

gcloud run deploy

Teraz działa:

ed288801c6825eb1.png

Możesz udostępnić ten adres URL, aby każdy, kto potrzebuje narzędzia do konwersji liczb rzymskich, mógł z niego korzystać.

8. Opcjonalnie: popraw wygląd

Aplikacja działa prawidłowo i jest dostępna dla każdego użytkownika internetu. Ale wygląda trochę zwyczajnie. Zanim poinformujesz o tym wszystkich, zapytaj Gemini Code Assist o poprawienie wyglądu.

Otwórz plik templates/index.html. W oknie czatu z Gemini zapytaj:

Make this index.html file use material design.

Odpowiedź polega na dodaniu do bieżącego pliku elementów, które spowodują, że będzie on wyglądać mniej więcej tak:

<!DOCTYPE html>
<html>
<head>
    <title>Roman Numerals</title>
    <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">   
    <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>     
</head>
<body>
    <h1 class="mdl-typography--title">Roman Numerals</h1>
    <form action="/convert" method="post">
        <div class="mdl-textfield mdl-js-textfield">
            <input class="mdl-textfield__input" type="text" id="number" name="number" required />
            <label class="mdl-textfield__label" for="number">Enter a number:</label>
          </div>
          <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
            Convert!
          </button>
    </form>
</body>
</html>

Kliknij ikonę, aby skopiować sugerowany kod i wkleić go w miejsce dotychczasowej zawartości pliku index.html. W terminalu uruchom python3 main.py i kliknij link, aby otworzyć okno podglądu. Strona jest teraz nieco mniej prosta:

295643ec03fcaafc.png

Jeśli chcesz, możesz powtórzyć tę czynność w przypadku pliku convert.html.

Gemini Code Assist ma sporą wiedzę o CSS i może Ci pomóc w różnych aspektach stylizowania stron aplikacji. To dopiero początek.

Jeśli chcesz udostępnić tę aplikację, nie zapomnij ponownie wdrożyć jej w Cloud Run:

gcloud run deploy

Możesz przekazać adres URL osobom, które muszą przekonwertować liczby na cyfry rzymskie.

9. Gratulacje!

Gratulacje! Udało Ci się dodać testy do aplikacji, naprawić w niej błędy i dodać ulepszone funkcje za pomocą Gemini Code Assist.

Gdy skończysz korzystać z utworzonej aplikacji, możesz ją usunąć z panelu konsoli w chmurze, aby uniknąć potencjalnych przyszłych opłat.

Dokumentacja referencyjna...