- първи PHP unit test • 2009 - първи Ruby on Rails проект • 2009 - първи Ruby unit test • 2010 - официално Ruby developer • 2010 - първи selenium acceptance test • 2014 - все още пиша главно на Ruby … :P
автоматичен тест? • Какви видове тестове има? • Какво е добър тест? • Как да пишем добри тестове? • Какво трябва да тестваме? • Какво са “Mocks”? • Какво е “RSpec”? • Какво е “Test Driven Development”? • Какво е “Fragile tests”?
features • Forces you to understand the features and communication between components • Reduces the cost for new features • Making code testable decreases complexity and modularity
1').value end def test_subtract assert_equal 1, Calculation.new('2 - 1').value end def test_multiply assert_equal 6, Calculation.new('3 * 2').value end end
one “component” Tests the whole stack Isolated with mocks Some times uses stubs Uses the UI Expresses domain terms Fast Slow Very slow Helps for good design Helps for verification Helps for verification
order.user assert !order.valid? def Order.can_be_processed_today? true end assert order.valid? order.cancel assert_equal :canceled, order.state end end
describe "GET 'index'" do it "responds with posts of a given category" do allow(Post).to receive(:for_category).with(‘1’).and_return [post] get :index, category_id: '1' expect(controller).to respond_with [post] end end describe "POST 'create'" do it "creates new post" do allow(Post).to receive(:create).and_return post post :create, post: {title: 'test'} expect(Post).to have_received(:create).with(user: current_user, title: 'tes end end end
{ '+' => ->(a, b) { a + b }, '-' => ->(a, b) { a - b }, '*' => ->(a, b) { a * b } } def value a, operand, b = @expression.split ' ' operation = OPERATIONS[operand] raise "Can't parse expression - #{@expression}" unless operation operation.call a.to_i, b.to_i end end
{ '+' => ->(a, b) { a + b }, '-' => ->(a, b) { a - b }, '*' => ->(a, b) { a * b }, '/' => ->(a, b) { a / b } } def value a, operand, b = @expression.split ' ' operation = OPERATIONS[operand] raise "Can't parse expression - #{@expression}" unless operation operation.call a.to_f, b.to_f end end
a + b }, '-' => ->(a, b) { a - b }, '*' => ->(a, b) { a * b }, '/' => ->(a, b) { a / b } } attr_reader :expression def initialize(expression) @expression = expression end def value @value ||= calculate_value end def to_s “#{expression} = #{value}" end private def calculate_value left, operand, right = expression.split ' ' operation = OPERATIONS[operand] raise "Can't parse expression - #{@expression}" unless operation operation.call left.to_f, right.to_f end end
by text mask" do task = create_task text: 'Create slides' other = create_task text: 'Create examples' Task.complete_all query: 'slides' expect(Task.ongoing).to eq [task] end end end ✗
it "selects ongoing tasks" do ongoing = create_task state: :ongoing completed = create_task state: :completed expect(Task.ongoing).to eq ongoing end end end ✔
amount) return false if @gateway.active? processor = @gateway.processor return false if processor.enough_money?(amount) processor.process amount end end
автоматичен тест? • Какви видове тестове има? • Какво е добър тест? • Как да пишем добри тестове? • Какво трябва да тестваме? • Какво са “Mocks”? • Какво е “RSpec”? • Какво е “Test Driven Development”? • Какво е “Fragile tests”?