Kurz: Ruby bringt Minitest mit; RSpec ist die beliebte Alternative. Ein Test ist eine Klasse mit Methoden, die mit test_ beginnen:
Teil des Kurses Ruby
Tests mit Minitest
Ruby bringt Minitest mit; RSpec ist die beliebte Alternative. Ein Test ist eine Klasse mit Methoden, die mit test_ beginnen:
require "minitest/autorun"
class Rechner
def addiere(a, b) = a + b
def teile(a, b)
raise ZeroDivisionError, "durch null" if b.zero?
a / b
end
end
class RechnerTest < Minitest::Test
def setup
@r = Rechner.new
end
def test_addition
assert_equal 5, @r.addiere(2, 3)
end
def test_teilen
assert_in_delta 2.5, @r.teile(5, 2.0), 0.001
end
def test_fehler
assert_raises(ZeroDivisionError) { @r.teile(1, 0) }
end
def test_enthaelt
assert_includes [1, 2, 3], 2
refute_nil @r
end
endRun options: --seed 12345
# Running:
....
Finished in 0.001s, 4000.0 runs/s, 6000.0 assertions/s.
4 runs, 6 assertions, 0 failures, 0 errors, 0 skipsSeed und Zeitangaben ändern sich bei jedem Lauf; wichtig ist die letzte Zeile mit der Zusammenfassung. Typische Assertions: assert, assert_equal, assert_nil, assert_raises, assert_includes, assert_in_delta, assert_match; Gegenstücke mit refute_.
RSpec liest sich wie eine Beschreibung:
RSpec.describe Rechner do
subject(:rechner) { described_class.new }
describe "#addiere" do
it "addiert zwei Zahlen" do
expect(rechner.addiere(2, 3)).to eq(5)
end
end
describe "#teile" do
it "wirft bei Division durch null" do
expect { rechner.teile(1, 0) }.to raise_error(ZeroDivisionError)
end
end
endStarten: rspec bzw. ruby test/rechner_test.rb.
Gems und Bundler
Pakete heißen Gems (rubygems.org). Bundler verwaltet sie projektweit:
gem install colorize # global installieren
gem list # installierte Gems
bundle init # Gemfile erzeugen
bundle add rack # Gem hinzufügen
bundle install # alle Gems installieren
bundle exec ruby app.rb # mit den Versionen aus Gemfile.lock startenDie Gemfile:
source "https://rubygems.org"
ruby "3.3.6"
gem "sinatra", "~> 4.0"
gem "sequel"
group :test do
gem "minitest"
gem "rack-test"
end~> 4.0 bedeutet “ab 4.0, aber unter 5.0”. Die Datei Gemfile.lock hält exakte Versionen fest und gehört ins Repository.
Ein eigenes Gem / Projekt strukturieren
mein_projekt/
├── Gemfile
├── lib/
│ ├── mein_projekt.rb
│ └── mein_projekt/rechner.rb
├── test/
│ └── rechner_test.rb
├── Rakefile
└── bin/mein_programm# lib/mein_projekt.rb
require_relative "mein_projekt/rechner"
module MeinProjekt
VERSION = "0.1.0"
endrequire_relative lädt Dateien relativ zur aktuellen Datei, require sucht im Ladepfad. Rake (Rakefile) ist Rubys Build-Werkzeug:
task default: :test
desc "Tests ausführen"
task :test do
ruby "test/rechner_test.rb"
endQualität
- RuboCop: Stilprüfung und Autokorrektur (
rubocop -A) - Sorbet / RBS / Steep: optionale Typisierung
- YARD: Dokumentation aus Kommentaren
- Debugger:
binding.irboderdebugim Code,byebug/pryals Alternativen
# Minimaler Selbsttest ohne Framework
def pruefe(name)
ergebnis = yield
puts "#{ergebnis ? 'OK ' : 'FAIL'} #{name}"
rescue => e
puts "FAIL #{name}: #{e.class}"
end
pruefe("Summe") { [1, 2, 3].sum == 6 }
pruefe("Reverse") { "abc".reverse == "cba" }
pruefe("Absichtlich falsch") { 1 + 1 == 3 }
pruefe("Fehler") { Integer("x") }Ausgabe:
OK Summe
OK Reverse
FAIL Absichtlich falsch
FAIL Fehler: ArgumentErrorMerke
- Minitest (eingebaut) und RSpec für Tests;
assert_equal,assert_raises - Gems von rubygems.org, Bundler (
Gemfile,Gemfile.lock,bundle exec) - Projektstruktur:
lib/,test/,Rakefile - RuboCop für Stil,
binding.irbzum Debuggen
Übungsaufgabe
Schreibe eine Klasse Stapel mit push, pop, leer? und drei Tests mit Minitest.
Quiz zur Selbstkontrolle
Wie heißen Ruby-Pakete?
- Gems (richtig)
- Wheels
- Crates
- Packs
Welche Datei legt exakte Gem-Versionen fest?
- Gemfile.lock (richtig)
- Gemfile
- Rakefile
- .ruby-version
Wie beginnen Minitest-Testmethoden?
- Mit test_ (richtig)
- Mit it_
- Mit spec_
- Mit check_
Weiter im Kurs
Zurück: Metaprogrammierung und Ruby-Idiome
Weiter: Web, Rails und Ökosystem
Alle Kapitel: Ruby im Überblick