SlideShare ist ein Scribd-Unternehmen logo
1 von 75
Downloaden Sie, um offline zu lesen
Testing Embedded Systems
With Cucumber
Ian Dees • @undees
CukeUp! NYC 2013
Plenty of Ruby, but...
There will be C
There will be C++
There will be C#
http://pragprog.com/
titles/dhwcr
discount code:
CucumberIanDees
The Embedded
Continuum
almost a
computer
chip and
some ROM
Simple devices
No Ruby, no Cucumber
Gray Code
A simple system to test
Feature: Gray Code
Scenario Outline: Counter
When I press the button
Then the LEDs should read "<leds>"
Examples:
| leds |
| ..O |
| .OO |
| .O. |
| OO. |
| OOO |
| O.O |
| O.. |
| ... |
Arduino
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
if (buttonPressed) {
counter = (counter + 1) % ENTRIES;
updateLeds();
}
delay(50);
}
Drive code directly
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
if (buttonPressed) {
counter = (counter + 1) % ENTRIES;
updateLeds();
}
delay(50);
}
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
if (buttonPressed) {
counter = (counter + 1) % ENTRIES;
updateLeds();
}
delay(50);
}
static bool isFakeButtonPressed;
class Bounce {
public:
// ...
bool risingEdge() {
bool result = isFakeButtonPressed;
isFakeButtonPressed = false;
return result;
}
};
extern "C" void press() {
isFakeButtonPressed = true;
}
const char* leds() {
static char buf[LEDS + 1] = {0};
for (int i = 0; i < LEDS; ++i) {
buf[i] = STATES[counter][i] == HIGH ?
'O' :
'.';
}
return buf;
}
https://github.com/ffi/ffi
FFI
require 'ffi'
module Arduino
extend FFI::Library
ffi_lib 'graycode'
attach_function :press, [], :void
attach_function :leds, [], :string
attach_function :setup, [], :void
attach_function :loop, [], :void
end
When /^I press the button$/ do
Arduino.press
Arduino.loop
end
Then /^the LEDs should read "(.*?)"$/ do
|leds|
expect(Arduino.leds).to eq(leds)
end
Cucumber Wire Protocol
Cucumber-CPP
https://github.com/cucumber/cucumber-cpp
host: localhost
port: 3902
features/step_definitions/cucumber.wire
When /^I press the button$/ do
Arduino.press
Arduino.loop
end
Then /^the LEDs should read "(.*?)"$/ do
|expected|
expect(Arduino.leds).to eq(expected)
end
WHEN("^I press the button$") {
press();
loop();
}
THEN("^the LEDs should read "(.*?)"$") {
REGEX_PARAM(string, expected);
BOOST_CHECK_EQUAL(leds(), expected);
}
Bespoke wire server
http://www.2600.com/code/212/listener.c
listen/accept/read/write
while(fgets(buf,sizeof buf,rStream)) {
respond_to_cucumber(wStream, buf);
}
step_matches
invoke
Two messages
Then the LEDs should read "..O"
➡
["step_matches",
{"name_to_match":
"the LEDs should read"}]
➡
["success",
[{"id":"1",
"args":[{"val":"..O",
"pos":"22"}]}]]
json spirit
http://www.codeproject.com/KB/recipes/
JSON_Spirit.aspx
extern "C" void respond_to_cucumber(
FILE* stream,
const char* message) {
string s = message;
Value v;
read(s, v);
Array& a = v.get_array();
string type = a[0].get_str();
// handle Cucumber message types
report_success(stream);
}
if (type == "step_matches") {
string name = step_name(v);
if (name == "I press the button") {
report_success(stream);
return;
} else if (...)
// ...
}
}
if (type == "step_matches") {
string name = step_name(v);
if (name == "I press the button") {
report_success(stream);
return;
} else if (...)
// ...
}
}
if (type == "step_matches") {
string name = step_name(v);
if (...) {
// ...
} else if (name.find("the LEDs") == 0)
const int START = 22;
string leds = name.substr(START, 3);
report_match(leds, START, stream);
return;
}
}
Then the LEDs should read "..O"
➡
["invoke",
{"id":"1",
"args":["..O"]}]
➡
["success", []]
if (type == "invoke") {
string id = step_id(v);
if (id == "0") {
press();
loop();
} else if (id == "1") {
// ...
}
}
}
if (type == "invoke") {
string id = step_id(v);
if (id == "0") {
press();
loop();
} else if (id == "1") {
// ...
}
}
}
if (type == "invoke") {
string id = step_id(v);
if (id == "0") {
// ...
} else if (id == "1") {
string expected = step_leds(v);
if (expected != leds()) {
report_failure("LEDs", stream);
return;
}
}
}
https://github.com/hparra/ruby-serialport
Serial
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
if (buttonPressed) {
counter = (counter + 1) % ENTRIES;
updateLeds();
}
delay(50);
}
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
if ( buttonPressed ) {
counter = (counter + 1) % ENTRIES;
updateLeds();
delay(50);
}
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
int command = (Serial.available() > 0 ?
Serial.read() :
-1);
if (isIncrement(buttonPressed, command)) {
counter = (counter + 1) % ENTRIES;
updateLeds();
} else if (isQuery(command)) {
Serial.write(leds());
Serial.write('n');
}
delay(50);
}
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
int command = (Serial.available() > 0 ?
Serial.read() :
-1);
if (isIncrement(buttonPressed, command)) {
counter = (counter + 1) % ENTRIES;
updateLeds();
} else if (isQuery(command)) {
Serial.write(leds());
Serial.write('n');
}
delay(50);
}
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
int command = (Serial.available() > 0 ?
Serial.read() :
-1);
if (isIncrement(buttonPressed, command)) {
counter = (counter + 1) % ENTRIES;
updateLeds();
} else if (isQuery(command)) {
Serial.write(leds());
Serial.write('n');
}
delay(50);
}
void loop() {
button.update();
bool buttonPressed = button.risingEdge();
int command = (Serial.available() > 0 ?
Serial.read() :
-1);
if (isIncrement(buttonPressed, command)) {
counter = (counter + 1) % ENTRIES;
updateLeds();
} else if (isQuery(command)) {
Serial.write(leds());
Serial.write('n');
}
delay(50);
}
require 'serialport'
module Arduino
@@port = SerialPort.open 2, 9600
at_exit { @@port.close }
def self.press
@@port.write '+'
end
def self.leds
@@port.write '?'
@@port.read.strip
end
end
Ruby, C#, SpecFlow, Cucumber
Almost a computer
Feature: Calculator
Scenario: Add two numbers
When I multiply 2 and 3
Then I should get 6
Run Cucumber directly
rsync -av --delete . remote1:test_path
ssh remote1 'cd test_path && cucumber'
Drive the GUI
TestStack White
https://github.com/TestStack/White
namespace Calc.Spec
{
[Binding]
public class CalculatorSteps
{
private Window window;
[Before]
public void Before()
{
Application application =
Application.Launch("calc.exe");
window =
application.GetWindow(
"Calculator",
InitializeOption.NoCache);
}
// ...
}
}
namespace Calc.Spec
{
[Binding]
public class CalculatorSteps
{
private Window window;
[Before]
public void Before()
{
Application application =
Application.Launch("calc.exe");
window =
application.GetWindow(
"Calculator",
InitializeOption.NoCache);
}
// ...
}
}
namespace Calc.Spec
{
[Binding]
public class CalculatorSteps
{
private Window window;
[Before]
public void Before()
{
Application application =
Application.Launch("calc.exe");
window =
application.GetWindow(
"Calculator",
InitializeOption.NoCache);
}
// ...
}
}
[When(@"I multiply (.*) and (.*)")]
public void WhenIMultiply(string a, string b)
{
window.Keyboard.Enter(a + "*" + b + "=");
}
[Then(@"I should get (.*)")]
public void ThenIShouldGet(string expected)
{
window.Get<Label>(expected);
}
Give your app an API
Mongoose web server
int main()
{
struct mg_context *ctx = mg_start();
mg_set_option(ctx, "ports", "33333");
mg_set_uri_callback(ctx, "/",
&show_index, 0);
mg_set_uri_callback(ctx, "/multiply",
&multiply, 0);
mg_set_uri_callback(ctx, "/result",
&get_result, 0);
getchar();
mg_stop(ctx);
return 0;
}
int main()
{
struct mg_context *ctx = mg_start();
mg_set_option(ctx, "ports", "33333");
mg_set_uri_callback(ctx, "/",
&show_index, 0);
mg_set_uri_callback(ctx, "/multiply",
&multiply, 0);
mg_set_uri_callback(ctx, "/result",
&get_result, 0);
getchar();
mg_stop(ctx);
return 0;
}
static void multiply(
struct mg_connection *conn,
const struct mg_request_info *request_info,
void *user_data)
{
char *ap = mg_get_var(conn, "multiplier");
char *bp = mg_get_var(conn, "multiplicand");
int a = atol(ap);
int b = atol(bp);
result = a * b;
mg_printf(conn,
"HTTP/1.1 200 OKrn
Content-Type: text/plainrnrn");
mg_free(multiplier_s);
mg_free(multiplicand_s);
}
static void multiply(
struct mg_connection *conn,
const struct mg_request_info *request_info,
void *user_data)
{
char *ap = mg_get_var(conn, "multiplier");
char *bp = mg_get_var(conn, "multiplicand");
int a = atol(ap);
int b = atol(bp);
result = a * b;
mg_printf(conn,
"HTTP/1.1 200 OKrn
Content-Type: text/plainrnrn");
mg_free(multiplier_s);
mg_free(multiplicand_s);
}
static void multiply(
struct mg_connection *conn,
const struct mg_request_info *request_info,
void *user_data)
{
char *ap = mg_get_var(conn, "multiplier");
char *bp = mg_get_var(conn, "multiplicand");
int a = atol(ap);
int b = atol(bp);
result = a * b;
mg_printf(conn,
"HTTP/1.1 200 OKrn
Content-Type: text/plainrnrn");
mg_free(multiplier_s);
mg_free(multiplicand_s);
}
static void multiply(
struct mg_connection *conn,
const struct mg_request_info *request_info,
void *user_data)
{
char *ap = mg_get_var(conn, "multiplier");
char *bp = mg_get_var(conn, "multiplicand");
int a = atol(ap);
int b = atol(bp);
result = a * b;
mg_printf(conn,
"HTTP/1.1 200 OKrn
Content-Type: text/plainrnrn");
mg_free(multiplier_s);
mg_free(multiplicand_s);
}
static void get_result(
struct mg_connection *conn,
const struct mg_request_info *request_info,
void *user_data)
{
mg_printf(conn,
"HTTP/1.1 200 OKrn
Content-Type: text/plainrnrn%d",
result);
}
https://github.com/jnunemaker/httparty
HTTParty
When(/^I multiply (d+) and (d+)$/) do |a, b|
Calculator.multiply a, b
end
Then(/^I should get (d+)$/) do |n|
expect(Calculator.result).to eq(n.to_i)
end
require 'httparty'
class Calculator
include HTTParty
base_uri 'localhost:33333'
def self.multiply(a, b)
get "/multiply?multiplier=#{a}
&multiplicand=#{b}"
end
def self.result
get("/result").to_i
end
end
(because tl;dr is passé)
In summary:
Have source? Device Technique
yes simple Direct
yes simple Serial
yes medium
Cucumber Wire
Protocol
yes powerful Custom TCP
no powerful GUI
Thank you
https://github.com/undees/cukeup

Weitere ähnliche Inhalte

Mehr von Skills Matter

Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applicationsSkills Matter
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmSkills Matter
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimSkills Matter
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Skills Matter
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlSkills Matter
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsSkills Matter
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Skills Matter
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Skills Matter
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldSkills Matter
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Skills Matter
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Skills Matter
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingSkills Matter
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveSkills Matter
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSkills Matter
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tSkills Matter
 

Mehr von Skills Matter (20)

Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4j
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
 
Plug 20110217
Plug   20110217Plug   20110217
Plug 20110217
 
Lug presentation
Lug presentationLug presentation
Lug presentation
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
 
Plug saiku
Plug   saikuPlug   saiku
Plug saiku
 
Huguk lily
Huguk lilyHuguk lily
Huguk lily
 

Kürzlich hochgeladen

Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Kürzlich hochgeladen (20)

Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Cukeup nyc ian dees on testing embedded systems with cucumber