Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing JavaScript in Rails Applications
Search
Vasili Kachalko
February 23, 2013
Programming
500
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing JavaScript in Rails Applications
Vasili Kachalko
February 23, 2013
Other Decks in Programming
See All in Programming
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
380
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
640
プロポーザルを書いてもらう
pvcresin
0
300
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
100
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.6k
Foundation Models frameworkで画像分析
ryodeveloper
1
600
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
380
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.5k
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
3
770
メールのエイリアス機能を履き違えない
isshinfunada
0
230
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
590
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
Featured
See All Featured
The browser strikes back
jonoalderson
0
1.5k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
690
Unsuck your backbone
ammeep
672
58k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.5k
Music & Morning Musume
bryan
47
7.3k
The Curious Case for Waylosing
cassininazir
1
450
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
650
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
460
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.3k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
380
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
250
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
200
Transcript
TESTING JS IN RAILS APPS and H. J. Simpson Vasili
Kachalko twitter.com/dreamfa11 github.com/dreamfall Brainspec brainspec.com Sunday, February 24, 13
CLIENT SIDE APPS PROS Sunday, February 24, 13
CLIENT SIDE APPS PROS • High speed Sunday, February 24,
13
CLIENT SIDE APPS PROS • High speed • Clients love
them Sunday, February 24, 13
CLIENT SIDE APPS PROS • High speed • Clients love
them • Server load reduction Sunday, February 24, 13
CLIENT SIDE APPS CONS Sunday, February 24, 13
CLIENT SIDE APPS CONS • Testing Sunday, February 24, 13
CLIENT SIDE APPS CONS • Testing • It’s JavaScript Sunday,
February 24, 13
TEST COVERAGE 100% Sunday, February 24, 13
APPLICATION LANGUAGES 63% 7% 30% ruby javascript coffeescript Sunday, February
24, 13
SO HOW SHOULD WE TEST JS Capybara? Sunday, February 24,
13
SO HOW SHOULD WE TEST JS Capybara? NO Sunday, February
24, 13
SOLUTIONS mocha* + chai * - mocha читается как “мока”.
Точно. Я проверял. Да, другой вариант смешнее. Sunday, February 24, 13
Sunday, February 24, 13
Sunday, February 24, 13
ASSERTIONS/MATCHERS Sunday, February 24, 13
ASSERTIONS/MATCHERS • to (should) • be • been • is
• that • and • have • with • .deep • .a(type) • .include(value) • .ok • .true • .false • .null • .undefined • .exist • .empty • .equal (.eql) • .above(value) • .below(value) • .within(start, finish) • .instanceof(constructor) • .property(name, [value]) • .ownProperty(name) • .length(value) • .match(regexp) • .string(string) • .keys(key1, [key2], [...]) • .throw(constructor) • .respondTo(method) • .satisfy(method) • .closeTo(expected, delta) Sunday, February 24, 13
EXAMPLE describe 'Foo', -> it 'returns omg', -> expect(Foo.bar).to.eq('omg') Foo.bar.should.eq('omg')
assert_equal(Foo.bar, 'omg') Sunday, February 24, 13
INTEGRATING WITH RAILS Sunday, February 24, 13
Sunday, February 24, 13
INSTALLATION # Gemfile gem 'konacha' # config/initializers/konacha.rb Konacha.configure do |config|
config.spec_dir = "spec/javascripts" config.spec_matcher = /_spec\.|_test\./ config.driver = :selenium config.stylesheets = %w(application) end if defined?(Konacha) Sunday, February 24, 13
EXAMPLE <div class="choo"> <input type="text"><a href="#">Do it</a> </div> app/views/home/index.html.erb Sunday,
February 24, 13
EXAMPLE app/assets/javascripts/application.js.coffee #= require jquery jQuery -> ($ document).delegate 'a',
'click', (e) -> do e.preventDefault ($ '.choo input').val 'CHOO CHOO!11' Sunday, February 24, 13
EXAMPLE spec/javascripts/spec_helper.js.coffee #= require_tree ./templates #= require application #= require
chai-jquery Sunday, February 24, 13
EXAMPLE spec/javascripts/templates/choo.jst.skim .choo input type="text" a href="#" | Do it
Sunday, February 24, 13
EXAMPLE spec/javascripts/application_spec.js.coffee #= require spec_helper describe 'Application', -> it 'works!',
-> ($ '#konacha').html JST['templates/choo']() do ($ '.choo a').click expect($ '.choo input').to.have.value 'CHOO CHOO!11' Sunday, February 24, 13
RUNNING rake konacha:run Sunday, February 24, 13
RUNNING rake konacha:serve http://0.0.0.0:3500/ Sunday, February 24, 13
EXAMPLE spec/javascripts/templates/choo.jst.skim .choo input type="text" a href="#" | Do it
gem ‘skim’ Sunday, February 24, 13
EXAMPLE spec/javascripts/application_spec.js.coffee #= require spec_helper describe 'Application', -> it 'works!',
-> ($ '#konacha').html JST['templates/choo']() do ($ '.choo a').click expect($ '.choo input').to.have.value 'CHOO CHOO!11' ??? Sunday, February 24, 13
Sunday, February 24, 13
chai-jquery gem ‘chai-jquery-rails’ Sunday, February 24, 13
CHAI-JQUERY MATCHERS • .attr(name[, value]) • .data(name[, value]) • .class(className)
• .id(id) • .html(html) • .text(text) • .value(value) • .visible • .hidden • .selected • .checked • .disabled • .exist • .match(selector) / .be(selector) • .contain(selector) • .have(selector) Sunday, February 24, 13
EXAMPLE app/assets/javascripts/application.js.coffee #= require jquery jQuery -> ($ document).delegate 'a',
'click', (e) -> do e.preventDefault if confirm 'Are you sure?' ($ '.choo input').val 'CHOO CHOO!11' Sunday, February 24, 13
Sunday, February 24, 13
Sunday, February 24, 13
sinon.js http://sinonjs.org/ Sunday, February 24, 13
SINON.JS •stubs •mocks •spies •fake timers •fake XHR •fake servers
•... Sunday, February 24, 13
spec/javascripts/spec_helper.coffee #= require_tree ./templates #= require chai-jquery #= require application
#= require support/sinon #= require_tree ./support # Needed for stubbing out "window" properties # like the confirm dialog Konacha.mochaOptions.ignoreLeaks = true beforeEach -> @sandbox = sinon.sandbox.create() afterEach -> @sandbox.restore() Sunday, February 24, 13
EXAMPLE spec/javascripts/application_spec.js.coffee #= require spec_helper describe 'Application', -> beforeEach ->
@sandbox.stub(window, "confirm").returns(true) it 'works!', -> ($ '#konacha').html JST['templates/choo']() do ($ '.choo a').click expect(($ '.choo input')).to.have.value 'CHOO CHOO!11' Sunday, February 24, 13
WHAT ABOUT AJAX REQUESTS? Sunday, February 24, 13
STUBBING AJAX RESPONSES #= require jquery jQuery -> $(document).delegate 'a',
'click', (e) -> do e.preventDefault $.get '/omg', (data) -> $('.choo input').val data Sunday, February 24, 13
STUBBING AJAX RESPONSES #= require spec_helper describe 'Application', -> beforeEach
-> @server = do sinon.fakeServer.create @server.respondWith '/omg', (xhr, params) -> xhr.respond 200, {'Content-Type': 'application/ text'}, 'CHOO CHOO!11' afterEach -> do @server.restore it 'works!', -> ($ '#konacha').html JST['templates/choo']() do ($ '.choo a').click do @server.respond expect(($ '.choo input')).to.have.value 'CHOO CHOO!11' Sunday, February 24, 13
THANK YOU twitter.com/HomerJSimpson twitter.com/dreamfa11 github.com/dreamfall Brainspec brainspec.com Sunday, February 24,
13