Travaille actuellement comme ingénieur dans la première année des nouveaux diplômés. J'avais peu d'expérience en ingénierie et je me demandais si je pourrais battre mes seniors en profitant de mon inexpérience.
Comme je suis inexpérimenté, je n'ai aucune habitude dans la procédure de montage. Parce que je n'ai pas d'habitude, j'ai décidé d'essayer de l'implémenter en utilisant TDD afin de prendre une bonne habitude (peut-être qu'il y avait une manière différente).
Essayez le développement TDD avec le Tutoriel Ruby on Rails. sample_app
[Développement piloté par les tests](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95% Jetez un coup d'œil à E9% 96% 8B% E7% 99% BA-Kent-Beck / dp / 4274217884)
[Développement piloté par les tests](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95% Regardez la vidéo de l'auteur de E9% 96% 8B% E7% 99% BA-Kent-Beck / dp / 4274217884). Clean code that works - How can we go there? - Takuto Wada | SeleniumConf Tokyo
Parcourez le matériel pour les sessions d'étude TDD en interne
Développement piloté par les tests. Avant l'implémentation, écrivez un test qui ne réussit que si l'implémentation réussit.
Rédiger un test (avant l'implémentation) ↓ Le test échoue (car je n'ai rien implémenté) ↓ Implémenter ↓ Les tests réussissent (car l'implémentation vous permet de passer les tests que vous avez écrits avant l'implémentation) ↓ Refactor. Si ce test réussit, nous pouvons dire que nous avons pu corriger le code sans perdre de fonctionnalités. Au contraire, si le test échoue en raison du refactoring, la fonction qui aurait dû être implémentée a été perdue, donc déboguez-la.
Avantages du TDD
Inconvénients du TDD
Afin de supprimer les inconvénients du TDD et d'en tirer parti, il est nécessaire d'avoir un index du moment à TDD.
En bref, vous pouvez essayer le TDD de base, mais si vous ne savez pas comment écrire un test, vous ne devriez pas faire de TDD.
Voici un exemple concret de test avec TDD. L'explication utilise différents types de test (modèle, contrôleur, intégration, etc.), donc si vous n'êtes pas familier avec les types de test, veuillez jeter un œil ici. Structure du répertoire de test Rails et processus de test
Succès sur demande ou vérification de l'existence des éléments requis (test simple du contrôleur). Il est bon d'écrire d'abord un test de confirmation simple
controller_test.rb
#Test du contrôleur
test "should get home" do
get root_path
assert_response :success is #La demande aboutit-elle?
assert_select "title", "HOME TITLE" #Le titre de la page est-il HOME TITLE?
end
Commencez par écrire un test qui réussira si la validation réussit. (Exemple: test de modèle, test d'intégration pour vérifier le résultat de la transmission du formulaire)
user_test.rb
#Test du modèle utilisateur
#Ecrivez le test suivant avant de décrire le contenu de validation dans le modèle utilisateur
def setup
@user = User.new(name: "Example User", email: "[email protected]",
password: "hogehoge", password_confirmation: "hogehoge")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = " "
assert_not @user.valid?
end
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
users_signup_test.rb
#Nouveau test d'inscription(integration_test)je fais
#Un test que vous souhaitez échouer lors de la tentative d'enregistrement avec un paramètre qui devient invalide
test "invalid signup information" do
get signup_path
assert_no_difference 'User.count' do
post users_path, params: { user: { name: "",
email: "user@invalid",
password: "foo",
password_confirmation: "bar" } }
end
end
Il n'y a pas d'énoncé d'erreur particulier, mais écrivez d'abord le test lorsqu'il ne fonctionne pas comme prévu. Écrivez un test qui réussit uniquement lorsqu'il fonctionne comme vous le souhaitez, puis apportez des modifications au code pour qu'il fonctionne comme vous le souhaitez.
Le processus de déconnexion sera décrit à titre d'exemple. J'ai fait référence au Tutoriel Ruby on Rails 9.14 (Deux bogues peu visibles).
Login_controller.rb
class LoginController < ApplicationController
.
.
def destroy #Action de déconnexion
log_out
redirect_to root_url
end
private #Désormais, la définition de la fonction utilisée dans l'action
#Détruire une session persistante
def forget(user)
user.forget #Vider le jeton de mémoire de connexion de l'utilisateur stocké dans la base de données
cookies.delete(:user_id) #Vider le contenu des cookies
cookies.delete(:remember_token)
end
#Déconnectez l'utilisateur actuel
#Courant indiquant l'utilisateur actuel_Vider le jeton de mémoire et la session de l'utilisateur,Courant variable_Vider le contenu de l'utilisateur
def log_out
forget(current_user)
session.delete(:user_id)
current_user = nil
end
end
Dans l'état de ce code, Ouvrez deux onglets dans votre navigateur et dans chaque onglet Supposons que vous soyez connecté avec le même utilisateur.
Tout d'abord, déconnectez-vous dans un onglet. Ensuite, la valeur de current_user devient nulle. Après cela, lorsque j'essaie de me déconnecter sur l'autre onglet, current_user est nul, donc il devient nil.forget et une erreur se produit.
Dans une telle situation, on peut dire qu '"il n'y a pas d'énoncé d'erreur particulier, mais cela ne fonctionne pas comme je m'y attendais", alors je fais TDD. Commencez par rédiger un test pour voir s'il fonctionne correctement lorsque vous vous déconnectez deux fois.
users_login_test.rb
def setup #Définir l'instance utilisateur pour se connecter
@user = User.new(name: "Example User", email: "[email protected]",
password: "hogehoge", password_confirmation: "hogehoge")
end
test "two times logout after login" do
log_in(@user)
delete logout_path
assert_not is_logged_in?
assert_redirected_to root_url
#Simuler la déconnexion dans un autre onglet
delete logout_path
follow_redirect! #Lorsque vous redirigez, vérifiez s'il s'agit de la page avant de vous connecter
assert_select "a[href=?]", login_path #Vérifiez s'il existe un chemin pour la page de connexion
assert_select "a[href=?]", logout_path, count: 0
assert_select "a[href=?]", user_path(@user), count: 0
end
Apportez des modifications fonctionnelles pour réussir ce test. Enfin, ajoutez le code suivant et le test passera.
Login_controller.rb
class LoginController < ApplicationController
.
.
def destroy #Action de déconnexion
log_out if logged_in? #Utiliser la fonction de déconnexion uniquement dans l'état de connexion
redirect_to root_url
end
end
[Développement piloté par les tests](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9 J'ai appris les astuces à utiliser lors de la mise en œuvre de TDD dans le livre% 96% 8B% E7% 99% BA-Kent-Beck / dp / 4274217884).
Dans ce livre, il était écrit qu'au moins la création de test-> l'implémentation provisoire-> la triangulation-> le refactoring devrait être fait.
Cette fois, je vais donner un exemple de TDD pour créer une fonction qui renvoie l'argument d'entrée (int) sous forme de chaîne de caractères.
Créez un test pour la fonction (pas encore créée). Au moment de la création, le test sera rouge.
test "Pattern1 of test returnString function " do
a = returnString(1)
assert_equal a, "1"
end
Définissez une fonction qui passera le test écrit ci-dessus sous n'importe quelle forme. Le test devient vert dans la définition de la fonction.
def returnString(int)
return "1"
end
Créez plusieurs tests du même type (deux cette fois) et réécrivez l'implémentation sous une forme générale pour que le test du Rera réussisse.
Lorsque je crée ce test, il devient rouge. Parce que l'implémentation actuelle ne renvoie que "1".
test "Pattern2 of test returnString function " do
b = returnString(2)
assert_equal b, "2"
end
Passer d'une fonction qui renvoie une valeur brute de 1 à une fonction qui renvoie la valeur reçue en tant qu'argument sous forme de chaîne. Le test sera vert.
def returnString(int)
return "#{int}"
end
Même si vous faites TDD pour l'implémentation minimale comme décrit ci-dessus, le code deviendra compliqué à mesure que vous souhaitez ajouter d'autres fonctions. mais c'est d'accord. Grâce à l'écriture du test, vous pouvez juger avec précision la fonction du code. Par conséquent, vous pouvez refactoriser en toute confiance.
En faisant TDD, vous pouvez penser à ce que vous voulez mettre en œuvre en premier. J'ai senti que cela rendait la mise en œuvre efficace. J'ai également pensé que l'écriture de tests faciliterait la maintenance du code car je pouvais refactoriser en toute confiance.
Non limité à TDD, lors de l'écriture d'un test, vous n'avez pas à essayer d'écrire plusieurs types de contenu de test à la fois. Si vous essayez d'écrire en même temps et que le contenu du test lui-même est erroné, vous tomberez
Il n'est pas bon d'écraser le contenu du test de manière aussi complète que le contenu ci-dessus. Si vous écrivez de manière trop complète (par exemple en vérifiant minutieusement l'existence d'éléments HTML), il faudra plus de temps pour maintenir et modifier le test lui-même s'il y a un changement dans la fonction à l'avenir.
Non limité à TDD, lors de l'écriture des tests de validation, vous devez écrire les deux tests lorsque vous voulez qu'ils fonctionnent et des tests lorsque vous ne voulez pas qu'ils fonctionnent.
users_signup_test.rb
#Tester une nouvelle inscription
#Un test que vous souhaitez échouer lors de la tentative d'enregistrement avec un paramètre qui devient invalide
test "invalid signup information" do
get signup_path
assert_no_difference 'User.count' do
post users_path, params: { user: { name: "",
email: "user@invalid",
password: "foo",
password_confirmation: "bar" } }
end
end
#Tests que vous souhaitez réussir lors de la tentative d'enregistrement avec des paramètres valides
test "valid signup information" do
get signup_path
assert_difference 'User.count', 1 do
post users_path, params: { user: { name: "Example User",
email: "[email protected]",
password: "password",
password_confirmation: "password" } }
end
end
controller
def create
if (user_id = session[:user_id])
.
.
else
raise #Si le test réussit, vous savez que cette partie n'a pas été testée → Ecrivez le test pour que cette partie soit testée
.
.
end
end
Tutoriel Ruby on Rails [Développement piloté par les tests](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9 % 96% 8B% E7% 99% BA-Kent-Beck / dp / 4274217884) Clean code that works - How can we go there? - Takuto Wada | SeleniumConf Tokyo