2010-12-13 9 views
7

Mam zamiar stworzyć wtyczkę, która wygeneruje kod aplikacji oparty na scenariuszach Ogórek, ale chcę się upewnić, że nie wymyślam tutaj koła. Czy ktoś jest świadomy wtyczki, która współpracuje z ogórkiem i generuje modele, kontrolery i widoki?Czy są jakieś wtyczki Railsowe, które mogą generować modele, widoki itp. Za pomocą scenariuszy Ogórek?

Tylko małe tło na temat tego, co próbuję zrobić, jeśli to nie ma sensu. Kiedy tworzę nową aplikację, tutaj jest mój workflow:

  1. Naszkicuj 2 typy projektów wysokiego poziomu na mojej tablicy. 1, który pokazuje modele i relacje, a drugi pokazuje niektóre prymitywne ekrany dla układów, formularzy itp.

  2. Napisz scenariusze ogórka na podstawie projektu na wysokim poziomie (ale o drobniejszym ziarnie). Wiele z tych kroków opisuje po prostu to, co zobaczę w danym widoku, a także zarys przepływu aplikacji. Uważam, że tworzenie wszystkich scenariuszy, które mogę wymyślić przed rozpoczęciem kodowania, jest lepsze niż robienie jednego po drugim i kodowanie po napisaniu każdego scenariusza.

  3. Prowadzę scenariusze ogórków i patrzę na pierwszą awarię i rozpoczynam kodowanie od tego miejsca. Zwykle mam przed instalacją dodatkową konfigurację do skonfigurowania aplikacji Rails zgodnie z moimi preferencjami i dołączam klejnoty, które będę używać. Znajduję również logiczną kolejność uruchamiania plików funkcji, ponieważ niektóre są zależne od innych. Oczywiście zaczynając od rzeczy takich jak uwierzytelnianie.

  4. Następnie używam generatorów Railsowych (rusztowanie lub tylko model), aby pomóc mi utworzyć kod potrzebny do przekazania scenariusza. Zmieniam niektóre szablony generatorów, aby dać mi to, czego chcę.

  5. Następnie poprawiam wygenerowany kod, jeśli to konieczne. Najczęściej wymaga to ustawienia relacji w modelu, pracy ze skojarzeniami w widokach i wszelkich innych niestandardowych funkcji, których nie może zapewnić rusztowanie.

  6. Biegnę moje migracje razie potrzeby

  7. Potem uruchom moje scenariusze i powtórzyć kroki 4-6 żadnych dopóki scenariusz przechodzi.

  8. Powtarzaj kroki 4-7, aż wszystkie scenariusze przejdą pomyślnie.

Mogę się mylić, ale myślę, że wielu ludzi prawdopodobnie używa podejścia podobnego do tego. Rzeczą, która mnie denerwuje jest to, że widzę wiele powielania pomiędzy pisaniem scenariuszy a generowaniem/podkręcaniem kodu. Chcę być w stanie wygenerować skelaton mojej aplikacji przy użyciu scenariuszy z ogórkiem i użyć definicji kroków, aby pomóc mi dostosować to, co jest generowane. Oto przykład:

Scenario: MODEL widget exists 
    Given a widget model exists 
    Then it should belong to a "manufacturer" 
    And it should have a "quantity:integer" field 
    And it should validate the presence of "quantity" 
    And it should have many "wadgets" 
    And it should accept nested attributes for "wadgets" 
    #etc... 

Scenario: VIEW new widget page 
    Given I am on the new widgets page 
    Then I should see a "quantity" field 
    And I should see a "wadgets:name" nested field 
    And I should see a button with text "Save Widget" 

Scenario: CONTROLLER widget is created 
    Given a new widget is created 
    Then I should be on the widgets page 

To generowania kodu tak:

#FROM SCENARIO 1 
class Widget < ActiveRecord::Base 
    has_many :wadgets 
    belongs_to :manufacturer 
    validates_presence_of :quantity 
    accepts_nested_attributes_for :wadgets 
end 

#FROM SCENARIO 1  
class CreateWidget < ActiveRecord::Migration 
    def self.up 
    create_table :widgets do |t| 
     t.integer :quantity, :null=>false 
     t.integer :manufacturer_id 

     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :widgets 
    end 
end 

#FROM SCENARIO 2 
#new.html.haml (using formtastic helpers) 
=semantic_form_for(@widget) do |f| 
    = f.inputs do 
    = f.input :quantity 
    = f.semantic_fields_for :wadgets do |wadget| 
     = location.input :name 
    = f.buttons 
    =f.commit_button "Save Widget" 

#FROM SCENARIO 3 (using inherited resources) 
class WidgetsController < InheritedResources::Base 
    def create 
    create!{ widget_urls } 
    end 
end 

To tylko psuedo w tym momencie, ale myślę, że będzie to prawdziwa oszczędność czasu, aby określić swoją aplikację w Ogórkowe scenariusze, a następnie wygeneruj kod na podstawie tego, co jest w tych scenariuszach. Umożliwiłoby to tworzenie testów i pisanie kodu w tym samym czasie. Nie musiałbyś wpisywać wszystkich pól dla wiersza poleceń generatora rusztowań, a on automatycznie ustawiałby powiązania i tworzył odpowiednie typy pól w widoku. Pozwoli to również zachować cały projekt funkcji w jednym pliku.Korzystając z tego podejścia, najpierw uruchom generator na scenariuszu, a następnie uruchom testy ogórka po generacji. Jeśli został poprawnie skonfigurowany, wszystko przejdzie za pierwszym razem i będziesz miał całkiem solidny prototyp, który możesz dostosować.

Czy są jakieś wtyczki przypominające ten rodzaj testowej kombinacji generowania?

I dziękuję, jeśli poświęciłeś czas na przeczytanie tego. Wiem, że to było trochę za długie.

+0

myślę, że to całkiem ciekawy pomysł, ja recon go byłaby praca dla Ragela – scaney

+0

Wow, to świetny pomysł! Nie słyszałem o niczym, co to robi. Jeśli pójdziesz dalej w swoim planie, byłbym bardzo zainteresowany użyciem tej wtyczki i być może również wnosząc wkład. Mam nadzieję, że będziesz na blogu obszernie o tym i może nawet pingować Ryana Batesa, aby mógł zrobić Railscast na ten temat, gwarantując w ten sposób ekspozycję na większość społeczności Rails. – Samo

+0

@Samo - Pracuję teraz nad prostym prototypem, próbując odgadnąć tajniki .. i prawdopodobnie będę o tym blogować w przyszłym tygodniu lub 2. Wyślę Ci link do repozytorium github po Włożyłem w to trochę pracy i sprawdziłem, czy jest to coś, z czym chcesz pomóc. Dzięki! – johnmcaliley

Odpowiedz

2

Myślę, że używanie tutaj ogórka nie jest zgodne z zamierzeniem.

Zakładam, że wszyscy zgadzamy się, że cechy ogórka powinny opisywać pewne cechy, które klient chce zobaczyć - w zasadzie przetłumaczyć karty historii (wymagania) na testy działające. Te historie nie powinny dotyczyć wdrażania modeli, kontrolerów i widoków. Powinien przetestować takie rzeczy, jak "kiedy kliknę przycisk X, powinienem przejść do strony Y, a moje zgłoszenie powinno zostać zatwierdzone." To tylko jeden duży test integracji, który symuluje interakcję między użytkownikiem a witryną. W twoim przykładzie szukasz określonych pól na stronie, które można niejawnie sprawdzić, mówiąc "kiedy wypełniłem pole ilości 5."

Do testowania zachowania modeli i ich interakcji z logiką biznesową, lepiej byłoby użyć narzędzia RSpec lub Test :: Unit - o wiele łatwiej jest pisać testy i kpić/drwić. Jestem pewien, że istnieją wtyczki generujące testy RSpec dla każdego pola/relacji w twoim modelu. Generatory rspec-rails już dla większości prac dla Ciebie, np. rails generate rspec:scaffold Post

Uważam, że najlepszym ulepszeniem szyn ogórków byłoby pozostawienie modelu i kontrolera testowania RSPec, ale następnie byłoby w stanie wygenerować standardowe akcje CRUD dla danego zasobu z generowanymi funkcjami ogórka, np. "Użytkownik powinien być w stanie stworzyć X. "

+0

Podoba mi się odpowiedź, nie ma takiej wtyczki, i najwyraźniej nie jest to dobry pomysł, testowanie funkcji rdzenia rdzenia powinno pojawić się tylko wtedy, gdy jest to naprawdę ważne, jak w niektórych specjalnych przypadkach. Pisanie testów dla każdej podstawowej części aplikacji oznaczałoby wiele wysiłku, który jest bezużyteczny - sprawia, że ​​więcej problemów niż rozwiązuje. Pisanie takich testów byłoby powtórzeniem kodu z modeli/kontrolerów/widoków, innymi słowy, każda zmiana w jednym wymuszałaby zmiany w drugim, powielonym, a nawet potrojonym wysiłku. – mpapis

3

Miałem ten sam pomysł kilka dni temu. Jednak po przemyśleniu tego więcej, porzucam pomysły generowania modeli z plików funkcji. Zamiast tego gram z dsl, który generuje modele/rusztowania/zasoby przy użyciu generatora szyn z dsl.

Po tym, jak to działa, myślałem o podłączeniu generatorów do tworzenia plików funkcji na podstawie dsl.

Mam uruchomiony wypustek, które ma następujące wejścia:

application :test do 
    model :survey do 
    attribute :name, :string 
    has_many :questions 
    end 
    model :question do 
    has_many :options 
    has_many :answers 
    belongs_to :survey 
    attribute :body, :string 
    end 
    model :option do 
    belongs_to :question 
    attribute :body, :string 
    attribute :selector, :string 

    end 
    model :result do 
    belongs_to :survey 
    has_many :answers 
    end 
    model :answer do 
    belongs_to :result 
    belongs_to :question 
    attribute :value, :string 
    end 
    gen 
end 

i drukuje następujący wynik:

rails new test 
cd test 
rails generate model survey name:string 
rails generate model question survey_id:integer body:string 
rails generate model option question_id:integer body:string selector:string 
rails generate model result survey_id:integer 
rails generate model answer result_id:integer question_id:integer value:string 
Updating class: Survey 
    has_many:questions 
Updating class: Question 
    belongs_to:survey 
    has_many:options 
    has_many:answers 
Updating class: Option 
    belongs_to:question 
Updating class: Result 
    belongs_to:survey 
    has_many:answers 
Updating class: Answer 
    belongs_to:result 
    belongs_to:question 

Steve

Powiązane problemy