SlideShare a Scribd company logo
1 of 53
Download to read offline
iOS BDD with Kiwi
https://github.com/process255/insta-test
Sean Dougherty
sean@process255.com
@sdougherty
process255.com
simpletomato.com
iOS engineer in Denver
writing iOS apps since 2010
web apps before that
Who am I?
iOS
Behavior Driven Development
with Kiwi
Insta-Test
https://github.com/process255/insta-test
An iOS App that displays the feed of popular
photos on Instagram.
Culture of testing.
Ruby On Rails
Objective-C
NO Culture of testing.
Ok, ALMOST no Culture of
testing.
Lots of Ruby developers are building iOS apps.
But... that is changing.
And they are bringing their tests with them.
But... that is changing.
What is TDD?
“Test driven development (TDD) is a software development
approach in which a test is written before writing the code.”
http://www.techopedia.com/
Why test our code?
“TDD encourages simple designs and inspires
confidence.”
Kent Beck, who is credited with having developed or
'rediscovered' the technique.
Why test our code?
Testing is another tool in our toolbox that helps us
build high quality software.
Why test our code?
A well maintained suite of tests gives
us confidence to refactor.
Why test our code?
Tests help new developers learn the code base and help
prevent new code from unknowingly breaking old code.
Why test our code?
Tests help us write better code.
Poorly written code is hard to test.Test driving our
code forces us to do better.
What is BDD?
Behavior Driven Development focuses and associates behavioral
specifications with each unit of software under development.
http://www.techopedia.com/
Apple’s OCUnit follows the traditional xUnit format.
Kiwi uses a specification format made popular by Ruby’s RSpec BDD library.
What is the difference?
Kiwi
OCUnit
it(@"should have 11 players", ^{
Team team = [Team team];
[[[team should] have:11] players];
});
- (void)testHasElevenPlayers
{
Team team = [Team team];
STAssertTrue(team.players == 11, @"should have 11 players");
}
Kiwi
What is it good at?
readable tests
testing asynchronous code
built in stubbing and mocking
partial mocking
What is it bad at?
helper methods
code reuse
clickable test failure messages
Kiwi specs read like a sentence.
The team, when newly created,
should have a name.
The team, when newly created,
should have 11 players.
describe(@"Team", ^{
context(@"when newly created", ^{
it(@"should have a name", ^{
Team team = [Team team];
[[team.name should] equal:@"Avalanche"];
});
it(@"should have 11 players", ^{
Team team = [Team team];
[[[team should] have:11] players];
});
});
});
describe(@"Subject", ^{
beforeAll(^{
...
});
afterAll(^{
...
});
beforeEach(^{
...
});
afterEach(^{
...
});
});
What do I want to test?
A pragmatic approach
Simple methods
Methods that take time (async)
RestKit’s Object Mapping
Testing Storyboards
How can I test it?
A pragmatic approach
Simple methods
- (NSString *)prettyTitle
context(@"-prettyTitle", ^{
it(@"should return 'Sean Dougherty: 1,000 likes", ^{
Instagram* instagram = [[Instagram alloc] init];
instagram.fullName = @"Sean Dougherty";
instagram.likeCount = 1000;
[[[instagram prettyTitle] should] equal:@"Sean Dougherty: 1,000 likes"];
});
});
Methods that take time (async)
- (void)loadPopularWithSuccess:failure:
it(@"should load 16 photos", ^{
__block RKMappingResult *result;
[service loadPopularWithSuccess:...)
{
result = mappingResult;
}
failure:nil];
[[expectFutureValue([result array]) shouldEventually] haveCountOf:16];
});
RestKit’s Object Mapping
specify(^{ [[mappingTest should] mapKeyPath:@"id"
toKeyPath:@"instagramID"
withValue:@"1"];});
Testing Storyboards
it(@"the tableView should exist", ^{
[vc.tableView shouldNotBeNil];
});
Mocking & Stubbing
__block InstaService *service;
beforeEach(^{
service = [KWMock mockForClass:[InstaService
class]];
});
Mocking
beforeEach(^{
Instagram *instagram = [[Instagram alloc] init];
instagram.thumbPath = @"thumb path";
instagram.prettyTitle = @"pretty title";
[vc stub:@selector(instagrams) andReturn:@[instagram]];
});
Stubbing
Testing Private Methods
and Private Properties
Use a class extension in your spec file
@interface InstaTableViewController ()
@property (nonatomic, copy) NSArray *instagrams;
- (void)loadPopular;
@end
Demo Time
Other Options
OCUnit (built into Xcode)
Cedar
https://github.com/pivotal/cedar
Expecta
https://github.com/specta/expecta
Specta
https://github.com/specta/specta
OCMock
https://github.com/erikdoe/ocmock
OCMockito
https://github.com/jonreid/OCMockito
Lots of others.
Resources
Insta-Test
https://github.com/process255/insta-test
Kiwi
https://github.com/allending/Kiwi
nsscreencast
http://nsscreencast.com/episodes/4-automated-testing-with-kiwi
Test Driving iOS Development with Kiwi by Daniel H Steinberg
https://itunes.apple.com/us/book/test-driving-ios-development/id502345143?mt=11
Attribution
Kiwi by Allen Ding
https://github.com/allending/Kiwi
AFNetworking by Matt Thompson and Scott
Raymond
https://github.com/AFNetworking/
AFNetworking
RestKit by Blake Watters
https://github.com/RestKit/RestKit
OHHTTPStubs by Olivier Halligon
https://github.com/AliSoftware/OHHTTPStubs
SDWebImage by Olivier Poitrey
https://github.com/rs/SDWebImage
SVProgressHUD by SamVermette
https://github.com/samvermette/
SVProgressHUD
CocoaPods by Eloy Durán
http://cocoapods.org/
ThankYou

More Related Content

What's hot

Stop coding start testing
Stop coding start testingStop coding start testing
Stop coding start testingPascal Dufour
 
Power-Up Your Test Suite with OLE Automation by Joshua Russell
Power-Up Your Test Suite with OLE Automation by Joshua RussellPower-Up Your Test Suite with OLE Automation by Joshua Russell
Power-Up Your Test Suite with OLE Automation by Joshua RussellQA or the Highway
 
Current Testing Challenges Ireland
Current Testing Challenges IrelandCurrent Testing Challenges Ireland
Current Testing Challenges IrelandDavid O'Dowd
 
Points.com fisheye crucible code reviews 2011
Points.com fisheye crucible code reviews 2011Points.com fisheye crucible code reviews 2011
Points.com fisheye crucible code reviews 2011pointstechgeeks
 
Test code that will not slow you down
Test code that will not slow you downTest code that will not slow you down
Test code that will not slow you downKostadin Golev
 
Automated Acceptance Tests & Tool choice
Automated Acceptance Tests & Tool choiceAutomated Acceptance Tests & Tool choice
Automated Acceptance Tests & Tool choicetoddbr
 
Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Danny Preussler
 
Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application TestingYnon Perek
 
B4USolution_API-Testing
B4USolution_API-TestingB4USolution_API-Testing
B4USolution_API-Testingb4usolution .
 
Crucible Product Overview
Crucible Product OverviewCrucible Product Overview
Crucible Product OverviewEllen Feaheny
 

What's hot (13)

Stop coding start testing
Stop coding start testingStop coding start testing
Stop coding start testing
 
Automated testing
Automated testingAutomated testing
Automated testing
 
SpecFlow for Agile Teams
SpecFlow for Agile TeamsSpecFlow for Agile Teams
SpecFlow for Agile Teams
 
Selenium Frameworks
Selenium FrameworksSelenium Frameworks
Selenium Frameworks
 
Power-Up Your Test Suite with OLE Automation by Joshua Russell
Power-Up Your Test Suite with OLE Automation by Joshua RussellPower-Up Your Test Suite with OLE Automation by Joshua Russell
Power-Up Your Test Suite with OLE Automation by Joshua Russell
 
Current Testing Challenges Ireland
Current Testing Challenges IrelandCurrent Testing Challenges Ireland
Current Testing Challenges Ireland
 
Points.com fisheye crucible code reviews 2011
Points.com fisheye crucible code reviews 2011Points.com fisheye crucible code reviews 2011
Points.com fisheye crucible code reviews 2011
 
Test code that will not slow you down
Test code that will not slow you downTest code that will not slow you down
Test code that will not slow you down
 
Automated Acceptance Tests & Tool choice
Automated Acceptance Tests & Tool choiceAutomated Acceptance Tests & Tool choice
Automated Acceptance Tests & Tool choice
 
Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)
 
Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application Testing
 
B4USolution_API-Testing
B4USolution_API-TestingB4USolution_API-Testing
B4USolution_API-Testing
 
Crucible Product Overview
Crucible Product OverviewCrucible Product Overview
Crucible Product Overview
 

Similar to I os tdd-with-bdd

QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...QAFest
 
Hotfixing iOS apps with Javascript
Hotfixing iOS apps with JavascriptHotfixing iOS apps with Javascript
Hotfixing iOS apps with JavascriptSergio Padrino Recio
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Railsbenlcollins
 
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...Future Processing
 
Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Gianluca Padovani
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWHolger Grosse-Plankermann
 
From 0 to 100: How we jump-started our frontend testing
From 0 to 100: How we jump-started our frontend testingFrom 0 to 100: How we jump-started our frontend testing
From 0 to 100: How we jump-started our frontend testingHenning Muszynski
 
Selenium withnet
Selenium withnetSelenium withnet
Selenium withnetVlad Maniak
 
Mobile Development integration tests
Mobile Development integration testsMobile Development integration tests
Mobile Development integration testsKenneth Poon
 
Java script unit testing
Java script unit testingJava script unit testing
Java script unit testingMats Bryntse
 
Device Testing with AWS Device Farm
Device Testing with AWS Device FarmDevice Testing with AWS Device Farm
Device Testing with AWS Device FarmAmazon Web Services
 
TDD super mondays-june-2014
TDD super mondays-june-2014TDD super mondays-june-2014
TDD super mondays-june-2014Alex Kavanagh
 
Testing Your App Before Launch: An Introduction to AWS Device Farm
Testing Your App Before Launch: An Introduction to AWS Device FarmTesting Your App Before Launch: An Introduction to AWS Device Farm
Testing Your App Before Launch: An Introduction to AWS Device FarmAmazon Web Services
 
Moving at light speed with continuous delivery
Moving at light speed with continuous deliveryMoving at light speed with continuous delivery
Moving at light speed with continuous deliveryRed Badger
 

Similar to I os tdd-with-bdd (20)

Object Calisthenics
Object CalisthenicsObject Calisthenics
Object Calisthenics
 
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
 
Hotfixing iOS apps with Javascript
Hotfixing iOS apps with JavascriptHotfixing iOS apps with Javascript
Hotfixing iOS apps with Javascript
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Rails
 
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
 
Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Tdd is not about testing (OOP)
Tdd is not about testing (OOP)
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRW
 
From 0 to 100: How we jump-started our frontend testing
From 0 to 100: How we jump-started our frontend testingFrom 0 to 100: How we jump-started our frontend testing
From 0 to 100: How we jump-started our frontend testing
 
Tdd is not about testing
Tdd is not about testingTdd is not about testing
Tdd is not about testing
 
Selenium withnet
Selenium withnetSelenium withnet
Selenium withnet
 
TDD & BDD
TDD & BDDTDD & BDD
TDD & BDD
 
Mobile Development integration tests
Mobile Development integration testsMobile Development integration tests
Mobile Development integration tests
 
Java script unit testing
Java script unit testingJava script unit testing
Java script unit testing
 
Device Testing with AWS Device Farm
Device Testing with AWS Device FarmDevice Testing with AWS Device Farm
Device Testing with AWS Device Farm
 
TDD super mondays-june-2014
TDD super mondays-june-2014TDD super mondays-june-2014
TDD super mondays-june-2014
 
Nativescript
NativescriptNativescript
Nativescript
 
Introduction to AWS Device Farm
Introduction to AWS Device FarmIntroduction to AWS Device Farm
Introduction to AWS Device Farm
 
Testing Your App Before Launch: An Introduction to AWS Device Farm
Testing Your App Before Launch: An Introduction to AWS Device FarmTesting Your App Before Launch: An Introduction to AWS Device Farm
Testing Your App Before Launch: An Introduction to AWS Device Farm
 
Moving at light speed with continuous delivery
Moving at light speed with continuous deliveryMoving at light speed with continuous delivery
Moving at light speed with continuous delivery
 
owasp top 10
owasp top 10owasp top 10
owasp top 10
 

Recently uploaded

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
"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
 
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
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
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
 
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
 
"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
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 

Recently uploaded (20)

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
"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
 
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
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
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
 
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
 
"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
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 

I os tdd-with-bdd