The document discusses client-side unit testing. It begins by noting common reasons developers give for not writing tests, such as believing tests are unnecessary or that code is too complex. It then explains the goals of introducing functional testing before unit testing, including automating manual testing and proving functionality from a user perspective without considering internal structure. The document contrasts functional and unit testing, noting unit testing focuses on complete isolation of individual units while functional testing covers most user cases. It argues that as programmers, writers should implement unit tests to ensure high quality code. The remainder covers best practices for unit testing including using a BDD framework, test organization into suites/specs/expectations, and examples of succinct testing syntax.
From a Joomla Day Midwest presentation, this focuses on unit testing in the open source Joomla project. The slides wrap around two demonstrations that cannot be included here.
In this experiential webinar, our guest Mohamed Shaaban will share with you his wide experience in Unit Testing in addition to practical techniques for unit testing your code using C#, NUnit, and Moq.
Software quality is critical to consistently and continually delivering new features to our users. This talk covers the importance of software quality and how to deliver it via unit testing, Test Driven Development and clean code in general.
This is the deck from a talk I gave at Desert Code Camp 2013.
When develpment met test(shift left testing)SangIn Choung
Sharing my thoughts and cases about co-work with test and developemnt. Two big approaches.
One is Engineering approach (
1. Early testing education
2. Test design
3. Test code guide
4. Pair-testing, programming
5. Test-Automation),
Second is Strategic activities (
1. Test Strategy/Plan
2. Test analysis/report)
Also, I wanted to mention tester's various career paths.
Thank you.
One reasonable definition of good design is testability. It is hard to imagine a software system that is both testable and poorly designed. It is also hard to imagine a software system that is well designed but also untestable.
I'll talk you through how bad design may affect testability. We will learn how to design robust tests which are not just increasing code coverage but are bringing real value to your project.
Finally we will explore the best way to integrate these tests to your continuous integration environment so they will be acting as top class guards against sloppy commits.
Keywords : design principles, unit tests, integration tests, stress tests, java, spring, junit @Rule, junit @Category, @RunWith, @Parameters, surefire, maven, jenkins, quality metrics, selenium , tdd, mocks, stubs, etc...
From a Joomla Day Midwest presentation, this focuses on unit testing in the open source Joomla project. The slides wrap around two demonstrations that cannot be included here.
In this experiential webinar, our guest Mohamed Shaaban will share with you his wide experience in Unit Testing in addition to practical techniques for unit testing your code using C#, NUnit, and Moq.
Software quality is critical to consistently and continually delivering new features to our users. This talk covers the importance of software quality and how to deliver it via unit testing, Test Driven Development and clean code in general.
This is the deck from a talk I gave at Desert Code Camp 2013.
When develpment met test(shift left testing)SangIn Choung
Sharing my thoughts and cases about co-work with test and developemnt. Two big approaches.
One is Engineering approach (
1. Early testing education
2. Test design
3. Test code guide
4. Pair-testing, programming
5. Test-Automation),
Second is Strategic activities (
1. Test Strategy/Plan
2. Test analysis/report)
Also, I wanted to mention tester's various career paths.
Thank you.
One reasonable definition of good design is testability. It is hard to imagine a software system that is both testable and poorly designed. It is also hard to imagine a software system that is well designed but also untestable.
I'll talk you through how bad design may affect testability. We will learn how to design robust tests which are not just increasing code coverage but are bringing real value to your project.
Finally we will explore the best way to integrate these tests to your continuous integration environment so they will be acting as top class guards against sloppy commits.
Keywords : design principles, unit tests, integration tests, stress tests, java, spring, junit @Rule, junit @Category, @RunWith, @Parameters, surefire, maven, jenkins, quality metrics, selenium , tdd, mocks, stubs, etc...
If you had an opportunity to build an application from the ground up, with testability a key design goal, what would you do?
In this presentation, we will look at just such a situation - a major, two year rewrite of a suite of core business systems. We will discuss how a system looks when testability is as important as functionality - and what it looks like when quality concerns are part of the initial design. We will look at the role of test automation and manual test in a modern project, and look at the tools and processes. The session will conclude with a demo of the latest visual test automation tool from MIT and a Q&A.
An introduction to unit testing using Visual Studio, C#, xUnit.net, and Moq. What it is, what is isn't, why we don't do it, how to design for testability, what to test, test driven development, unit testing frameworks, mocking libraries, how to get started.
A brief introduction to test automation covering different automation approaches, when to automate and by whom, commercial vs. open source tools, testability, and so on.
If you had an opportunity to build an application from the ground up, with testability a key design goal, what would you do?
In this presentation, we will look at just such a situation - a major, two year rewrite of a suite of core business systems. We will discuss how a system looks when testability is as important as functionality - and what it looks like when quality concerns are part of the initial design. We will look at the role of test automation and manual test in a modern project, and look at the tools and processes. The session will conclude with a demo of the latest visual test automation tool from MIT and a Q&A.
An introduction to unit testing using Visual Studio, C#, xUnit.net, and Moq. What it is, what is isn't, why we don't do it, how to design for testability, what to test, test driven development, unit testing frameworks, mocking libraries, how to get started.
A brief introduction to test automation covering different automation approaches, when to automate and by whom, commercial vs. open source tools, testability, and so on.
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldabaux singapore
How can we take UX and Data Storytelling out of the tech context and use them to change the way government behaves?
Showcasing the truth is the highest goal of data storytelling. Because the design of a chart can affect the interpretation of data in a major way, one must wield visual tools with care and deliberation. Using quantitative facts to evoke an emotional response is best achieved with the combination of UX and data storytelling.
Content personalisation is becoming more prevalent. A site, it's content and/or it's products, change dynamically according to the specific needs of the user. SEO needs to ensure we do not fall behind of this trend.
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
By David F. Larcker, Stephen A. Miles, and Brian Tayan
Stanford Closer Look Series
Overview:
Shareholders pay considerable attention to the choice of executive selected as the new CEO whenever a change in leadership takes place. However, without an inside look at the leading candidates to assume the CEO role, it is difficult for shareholders to tell whether the board has made the correct choice. In this Closer Look, we examine CEO succession events among the largest 100 companies over a ten-year period to determine what happens to the executives who were not selected (i.e., the “succession losers”) and how they perform relative to those who were selected (the “succession winners”).
We ask:
• Are the executives selected for the CEO role really better than those passed over?
• What are the implications for understanding the labor market for executive talent?
• Are differences in performance due to operating conditions or quality of available talent?
• Are boards better at identifying CEO talent than other research generally suggests?
Play with Testing on Android - Gilang Ramadhan (Academy Content Writer at Dic...DicodingEvent
Testing merupakan (QA) quality assurance dari sebuah produk. Dalam tahap ini kita jadi tahu, bila di dalam aplikasi yang kita buat terdapat bug, eror, atau salah dalam logika kode. Sehingga testing adalah bagian terpenting pada pengembangan aplikasi.
Eror bisa kita identifikasi jauh lebih dini sebelum proses produksi. Jika terjadi kesalahan dalam tahap produksi, itu sudah melibatkan user. Tentunya kerugian di dalam tahap ini akan lebih fatal. Faktanya, biaya perbaikan sebuah aplikasi eror di tahap produksi, lebih besar dibandingkan dengan biaya pengujian sebelum produksi.
Anda akan mempelajari:
- Mengapa perlu melakukan testing
- Apa sebenarnya yang dimaksud testing
- Apa saja tools yang bisa Anda manfaatkan
Enter the mind of an Agile Developer, BSG shares with you how we do software development and how to embed agile methodologies into your development process.
Learn about the benefits of writing unit tests. You will spend less time fixing bugs and you will get a better design for your software. Some of the questions answered are:
Why should I, as a developer, write tests?
How can I improve the software design by writing tests?
How can I save time, by spending time writing tests?
When should I write unit tests and when should I write system tests?
Fundamentals of software testing, testing levels and types, testing throughout the software life-cycle, bug report and bug severity.
Automated tests via selenium web-driver with a demo.
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...SOFTTECHHUB
The choice of an operating system plays a pivotal role in shaping our computing experience. For decades, Microsoft's Windows has dominated the market, offering a familiar and widely adopted platform for personal and professional use. However, as technological advancements continue to push the boundaries of innovation, alternative operating systems have emerged, challenging the status quo and offering users a fresh perspective on computing.
One such alternative that has garnered significant attention and acclaim is Nitrux Linux 3.5.0, a sleek, powerful, and user-friendly Linux distribution that promises to redefine the way we interact with our devices. With its focus on performance, security, and customization, Nitrux Linux presents a compelling case for those seeking to break free from the constraints of proprietary software and embrace the freedom and flexibility of open-source computing.
Sudheer Mechineni, Head of Application Frameworks, Standard Chartered Bank
Discover how Standard Chartered Bank harnessed the power of Neo4j to transform complex data access challenges into a dynamic, scalable graph database solution. This keynote will cover their journey from initial adoption to deploying a fully automated, enterprise-grade causal cluster, highlighting key strategies for modelling organisational changes and ensuring robust disaster recovery. Learn how these innovations have not only enhanced Standard Chartered Bank’s data infrastructure but also positioned them as pioneers in the banking sector’s adoption of graph technology.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
How to Get CNIC Information System with Paksim Ga.pptxdanishmna97
Pakdata Cf is a groundbreaking system designed to streamline and facilitate access to CNIC information. This innovative platform leverages advanced technology to provide users with efficient and secure access to their CNIC details.
“An Outlook of the Ongoing and Future Relationship between Blockchain Technologies and Process-aware Information Systems.” Invited talk at the joint workshop on Blockchain for Information Systems (BC4IS) and Blockchain for Trusted Data Sharing (B4TDS), co-located with with the 36th International Conference on Advanced Information Systems Engineering (CAiSE), 3 June 2024, Limassol, Cyprus.
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024Neo4j
Neha Bajwa, Vice President of Product Marketing, Neo4j
Join us as we explore breakthrough innovations enabled by interconnected data and AI. Discover firsthand how organizations use relationships in data to uncover contextual insights and solve our most pressing challenges – from optimizing supply chains, detecting fraud, and improving customer experiences to accelerating drug discoveries.
Climate Impact of Software Testing at Nordic Testing DaysKari Kakkonen
My slides at Nordic Testing Days 6.6.2024
Climate impact / sustainability of software testing discussed on the talk. ICT and testing must carry their part of global responsibility to help with the climat warming. We can minimize the carbon footprint but we can also have a carbon handprint, a positive impact on the climate. Quality characteristics can be added with sustainability, and then measured continuously. Test environments can be used less, and in smaller scale and on demand. Test techniques can be used in optimizing or minimizing number of tests. Test automation can be used to speed up testing.
Unlocking Productivity: Leveraging the Potential of Copilot in Microsoft 365, a presentation by Christoforos Vlachos, Senior Solutions Manager – Modern Workplace, Uni Systems
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
Full-RAG: A modern architecture for hyper-personalizationZilliz
Mike Del Balso, CEO & Co-Founder at Tecton, presents "Full RAG," a novel approach to AI recommendation systems, aiming to push beyond the limitations of traditional models through a deep integration of contextual insights and real-time data, leveraging the Retrieval-Augmented Generation architecture. This talk will outline Full RAG's potential to significantly enhance personalization, address engineering challenges such as data management and model training, and introduce data enrichment with reranking as a key solution. Attendees will gain crucial insights into the importance of hyperpersonalization in AI, the capabilities of Full RAG for advanced personalization, and strategies for managing complex data integrations for deploying cutting-edge AI solutions.
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIVladimir Iglovikov, Ph.D.
Presented by Vladimir Iglovikov:
- https://www.linkedin.com/in/iglovikov/
- https://x.com/viglovikov
- https://www.instagram.com/ternaus/
This presentation delves into the journey of Albumentations.ai, a highly successful open-source library for data augmentation.
Created out of a necessity for superior performance in Kaggle competitions, Albumentations has grown to become a widely used tool among data scientists and machine learning practitioners.
This case study covers various aspects, including:
People: The contributors and community that have supported Albumentations.
Metrics: The success indicators such as downloads, daily active users, GitHub stars, and financial contributions.
Challenges: The hurdles in monetizing open-source projects and measuring user engagement.
Development Practices: Best practices for creating, maintaining, and scaling open-source libraries, including code hygiene, CI/CD, and fast iteration.
Community Building: Strategies for making adoption easy, iterating quickly, and fostering a vibrant, engaged community.
Marketing: Both online and offline marketing tactics, focusing on real, impactful interactions and collaborations.
Mental Health: Maintaining balance and not feeling pressured by user demands.
Key insights include the importance of automation, making the adoption process seamless, and leveraging offline interactions for marketing. The presentation also emphasizes the need for continuous small improvements and building a friendly, inclusive community that contributes to the project's growth.
Vladimir Iglovikov brings his extensive experience as a Kaggle Grandmaster, ex-Staff ML Engineer at Lyft, sharing valuable lessons and practical advice for anyone looking to enhance the adoption of their open-source projects.
Explore more about Albumentations and join the community at:
GitHub: https://github.com/albumentations-team/albumentations
Website: https://albumentations.ai/
LinkedIn: https://www.linkedin.com/company/100504475
Twitter: https://x.com/albumentations
Removing Uninteresting Bytes in Software FuzzingAftab Hussain
Imagine a world where software fuzzing, the process of mutating bytes in test seeds to uncover hidden and erroneous program behaviors, becomes faster and more effective. A lot depends on the initial seeds, which can significantly dictate the trajectory of a fuzzing campaign, particularly in terms of how long it takes to uncover interesting behaviour in your code. We introduce DIAR, a technique designed to speedup fuzzing campaigns by pinpointing and eliminating those uninteresting bytes in the seeds. Picture this: instead of wasting valuable resources on meaningless mutations in large, bloated seeds, DIAR removes the unnecessary bytes, streamlining the entire process.
In this work, we equipped AFL, a popular fuzzer, with DIAR and examined two critical Linux libraries -- Libxml's xmllint, a tool for parsing xml documents, and Binutil's readelf, an essential debugging and security analysis command-line tool used to display detailed information about ELF (Executable and Linkable Format). Our preliminary results show that AFL+DIAR does not only discover new paths more quickly but also achieves higher coverage overall. This work thus showcases how starting with lean and optimized seeds can lead to faster, more comprehensive fuzzing campaigns -- and DIAR helps you find such seeds.
- These are slides of the talk given at IEEE International Conference on Software Testing Verification and Validation Workshop, ICSTW 2022.
9. You think
• Tests are not necessary and irrelevant
10. You think
• Tests are not necessary and irrelevant
• Manual testing is enough
11. You think
• Tests are not necessary and irrelevant
• Manual testing is enough
• Lacking of specification
12. You think
• Tests are not necessary and irrelevant
• Manual testing is enough
• Lacking of specification
• Spaghetti code are hard for testing
13. You think
• Tests are not necessary and irrelevant
• Manual testing is enough
• Lacking of specification
• Spaghetti code are hard for testing
• Web application needs functional testing rather
than unit testing
14. You think
• Tests are not necessary and irrelevant
• Manual testing is enough
• Lacking of specification
• Spaghetti code are hard for testing
• Web application needs functional testing rather
than unit testing
• Unit testing looks like only useful for back-end
code rather than front-end
15. You think
• Tests are not necessary and irrelevant
• Manual testing is enough
• Lacking of specification
• Spaghetti code are hard for testing
• Web application needs functional testing rather
than unit testing
• Unit testing looks like only useful for back-end
code rather than front-end
• Lazy...
21. What is functional testing
Functional testing is a type of black box
testing that bases its test cases on the
specifications of the software component
under test. Functions are tested by feeding
them input and examining the output, and
internal program structure is rarely
considered.
22. What is functional testing
Functional testing is a type of black box
testing that bases its test cases on the
specifications of the software component
under test. Functions are tested by feeding
them input and examining the output, and
internal program structure is rarely
considered.
25. In a nutshell
• Written from user perspective
• Proving users are able to reproduce defined steps
26. In a nutshell
• Written from user perspective
• Proving users are able to reproduce defined steps
• Don’t need to consider internal program structure
27. In a nutshell
• Written from user perspective
• Proving users are able to reproduce defined steps
• Don’t need to consider internal program structure
• Automating manual testing
29. What is unit testing
unit testing is a method by which individual
units of source code, sets of one or more
computer program modules together with
associated control data, usage procedures, and
operating procedures, are tested to determine
if they are fit for use.
30. What is unit testing
unit testing is a method by which individual
units of source code, sets of one or more
computer program modules together with
associated control data, usage procedures, and
operating procedures, are tested to determine
if they are fit for use.
33. In a nutshell
• Unit testing is complete isolation
• Must irrelevant to external dependencies
34. In a nutshell
• Unit testing is complete isolation
• Must irrelevant to external dependencies
• All unreliable or slow dependencies of a
tested unit should be stubbed
35. In a nutshell
• Unit testing is complete isolation
• Must irrelevant to external dependencies
• All unreliable or slow dependencies of a
tested unit should be stubbed
• Only the logic of that single unit is exercised
36. In a nutshell
• Unit testing is complete isolation
• Must irrelevant to external dependencies
• All unreliable or slow dependencies of a
tested unit should be stubbed
• Only the logic of that single unit is exercised
• Must be fast
38. What are differences between
functional and unit testing
unit functional
perspective programmer user
every module every process
goal
works as expected works as expected
all cases
coverage most user cases
even edge cases
result programmer :) user :)
39. What are differences between
functional and unit testing
unit functional
perspective programmer user
every module every process
goal
works as expected works as expected
all cases
coverage most user cases
even edge cases
result programmer :) user :)
40. What are differences between
functional and unit testing
unit functional
perspective programmer user
every module every process
goal
works as expected works as expected
all cases
coverage most user cases
even edge cases
result programmer :) user :)
41. What are differences between
functional and unit testing
unit functional
perspective programmer user
every module every process
goal
works as expected works as expected
all cases
coverage most user cases
even edge cases
result programmer :) user :)
42. What are differences between
functional and unit testing
unit functional
perspective programmer user
every module every process
goal
works as expected works as expected
all cases
coverage most user cases
even edge cases
result programmer :) user :)
49. Why need unit testing
• Ensuring every component is bug-free
50. Why need unit testing
• Ensuring every component is bug-free
• Ensuring every component is easy to modify
51. Why need unit testing
• Ensuring every component is bug-free
• Ensuring every component is easy to modify
• Easy to locating bug of complex logic
52. Why need unit testing
• Ensuring every component is bug-free
• Ensuring every component is easy to modify
• Easy to locating bug of complex logic
• Preventing and capturing regression bug
53. Why need unit testing
• Ensuring every component is bug-free
• Ensuring every component is easy to modify
• Easy to locating bug of complex logic
• Preventing and capturing regression bug
• Testable code must be high readability and
maintainability code
54. Why need unit testing
• Ensuring every component is bug-free
• Ensuring every component is easy to modify
• Easy to locating bug of complex logic
• Preventing and capturing regression bug
• Testable code must be high readability and
maintainability code
• and so on...
56. When to do unit testing
• When you write your own classes, modules,
libraries, frameworks.
57. When to do unit testing
• When you write your own classes, modules,
libraries, frameworks.
• You don’t need to write test code for
fundamental framework
59. testing style comparison
TDD BDD
based on function oriented feature oriented
syntax testing language idiomatic
spring from programmer stakeholder || PO
accumulation test as code test as documentation
60. testing style comparison
TDD BDD
based on function oriented feature oriented
syntax testing language idiomatic
spring from programmer stakeholder || PO
accumulation test as code test as documentation
61. testing style comparison
TDD BDD
based on function oriented feature oriented
syntax testing language idiomatic
spring from programmer stakeholder || PO
accumulation test as code test as documentation
62. testing style comparison
TDD BDD
based on function oriented feature oriented
syntax testing language idiomatic
spring from programmer stakeholder || PO
accumulation test as code test as documentation
63. testing style comparison
TDD BDD
based on function oriented feature oriented
syntax testing language idiomatic
spring from programmer stakeholder || PO
accumulation test as code test as documentation
72. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
73. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
74. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
• Support spec helper
75. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
• Support spec helper
• Be able to extend matcher
76. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
• Support spec helper
• Be able to extend matcher
• Be able to run in several environments
77. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
• Support spec helper
• Be able to extend matcher
• Be able to run in several environments
1. Browser
78. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
• Support spec helper
• Be able to extend matcher
• Be able to run in several environments
1. Browser
2. CI
79. BDD Framework
• Focuses on assertion, doesn’t depend on DOM
• Succinct API
• Natively support Spy
• Support spec helper
• Be able to extend matcher
• Be able to run in several environments
1. Browser
2. CI
3. NodeJS
80. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
afterEach(function () {
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
});
81. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard'); Suite
});
afterEach(function () {
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
});
82. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
afterEach(function () { Inner Suite
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
});
83. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
afterEach(function () {
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
});
"IsWordIKnow": false
Spec
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
});
84. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
afterEach(function () {
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url); Expectation
});
});
85. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
afterEach(function () {
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
}); Matcher
86. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard'); Setup
});
afterEach(function () {
});
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
});
87. Typical Spec & Succinct API
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard'); Setup
});
afterEach(function () {
}); Tear down
describe(“when initialized”, function() {
beforeEach(function() {
this.flashcard = new this.Flashcard({
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
});
});
it(“composite key should be composed by ContentId and IsWord properties”,
function() {
var expected_url = this.flashcard.get('ContentId') + '-' +
this.flashcard.get('IsWord');
expect(this.flashcard.id).toEqual(expected_url);
});
});
91. Spec Helper
beforeEach(function() {
this.fixtures = {
Flashcard: {
valid: { // response starts here
"Value": "here",
"Translation": "这儿",
"Audio": "here_en.mp3",
"IsWord": true,
"ContentId": 174087,
"IsWordIKnow": false
},
error: { // response starts here
"ErrorCode": "101",
"IsSuccess": "false"
}
}
}
Using this.fixtures.Flashcard.valid to access pre-defined fixture
for testing when this spec file is included in your spec runner.
92. Spy
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
describe(“when initialized”, function() {
beforeEach(function() {
spyOn(jQuery, ‘ajax’);
this.flashcard = new this.Flashcard();
this.flashcard.fetch();
});
it(“should communicate with back-end via http get method”, function() {
expect(jQuery.ajax).toHaveBeenCalled();
expect(jQuery.ajax.mostRecentCall.args[0].type).toEqual(‘GET’);
});
});
});
93. Spy
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
describe(“when initialized”, function() {
beforeEach(function() {
spyOn(jQuery, ‘ajax’); spy on instance method
this.flashcard = new this.Flashcard();
this.flashcard.fetch();
});
it(“should communicate with back-end via http get method”, function() {
expect(jQuery.ajax).toHaveBeenCalled();
expect(jQuery.ajax.mostRecentCall.args[0].type).toEqual(‘GET’);
});
});
});
94. Spy
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
describe(“when initialized”, function() {
beforeEach(function() {
spyOn(jQuery, ‘ajax’);
this.flashcard = new this.Flashcard();
this.flashcard.fetch();
}); original function won’t be called
it(“should communicate with back-end via http get method”, function() {
expect(jQuery.ajax).toHaveBeenCalled();
expect(jQuery.ajax.mostRecentCall.args[0].type).toEqual(‘GET’);
});
});
});
95. Spy
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
describe(“when initialized”, function() {
beforeEach(function() {
spyOn(jQuery, ‘ajax’);
this.flashcard = new this.Flashcard();
this.flashcard.fetch();
});
it(“should communicate with back-end via http get method”, function() {
expect(jQuery.ajax).toHaveBeenCalled();
expect(jQuery.ajax.mostRecentCall.args[0].type).toEqual(‘GET’);
});
}); match spied function was called
});
96. Spy
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
describe(“when initialized”, function() {
beforeEach(function() {
spyOn(jQuery, ‘ajax’);
this.flashcard = new this.Flashcard();
this.flashcard.fetch();
});
it(“should communicate with back-end via http get method”, function() {
expect(jQuery.ajax).toHaveBeenCalled();
expect(jQuery.ajax.mostRecentCall.args[0].type).toEqual(‘GET’);
});
});
}); arguments of last call
97. Spy
describe("Flashcard model", function () {
beforeEach(function () {
this.Flashcard = require('models/Flashcard');
});
describe(“when initialized”, function() {
beforeEach(function() {
spyOn(jQuery, ‘ajax’);
this.flashcard = new this.Flashcard();
this.flashcard.fetch();
});
it(“should communicate with back-end via http get method”, function() {
expect(jQuery.ajax).toHaveBeenCalled();
expect(jQuery.ajax.mostRecentCall.args[0].type).toEqual(‘GET’);
});
});
}); arguments of last call type of first argument
98. Extending Matcher
<a href=”#” class=”link”>this is a link</a>
expect($(‘a’).hasClass('s-selected')).toBeTruthy();
expectation failed:
Expected false to be truthy.
99. Extending Matcher
<a href=”#” class=”link”>this is a link</a>
expect($(‘a’).hasClass('s-selected')).toBeTruthy();
expectation failed:
Expected false to be truthy.
jasmine-jquery comes to rescue
100. Matcher from
jasmine jquery
<a href=”#” class=”link”>this is a link</a>
expect($(‘a’).hasClass('s-selected')).toBeTruthy();
expectation failed:
Expected false to be truthy.
101. Matcher from
jasmine jquery
<a href=”#” class=”link”>this is a link</a>
expect($(‘a’).hasClass('s-selected')).toBeTruthy();
expectation failed:
Expected false to be truthy.
expect($(‘a’).toHaveClass(‘s-selected’);
102. Matcher from
jasmine jquery
<a href=”#” class=”link”>this is a link</a>
expect($(‘a’).hasClass('s-selected')).toBeTruthy();
expectation failed:
Expected false to be truthy.
expect($(‘a’).toHaveClass(‘s-selected’);
expectation failed:
103. Matcher from
jasmine jquery
<a href=”#” class=”link”>this is a link</a>
expect($(‘a’).hasClass('s-selected')).toBeTruthy();
expectation failed:
Expected false to be truthy.
expect($(‘a’).toHaveClass(‘s-selected’);
expectation failed:
Expected '<a></a>' to have class 's-selected'.
104. jasmine-jquery features
• a set of custom matchers for jQuery
framework
• an API for handling HTML fixtures in your
specs
109. Recap rules of Unit Testing
• Unit testing is complete isolation
• Must irrelevant to external dependencies
• All unreliable or slow dependencies of a
tested unit should be stubbed
• Only the logic of that single unit is exercised
• Must be fast
110. Recap rules of Unit Testing
• Unit testing is complete isolation
• Must irrelevant to external dependencies
• All unreliable or slow dependencies of a
tested unit should be stubbed
• Only the logic of that single unit is exercised
• Must be fast
113. Stub every dependency
• Native spy feature of Jasmine is not enough
• It doesn’t support fake timer
114. Stub every dependency
• Native spy feature of Jasmine is not enough
• It doesn’t support fake timer
• It doesn’t support fake HTTP server
115. Stub every dependency
• Native spy feature of Jasmine is not enough
• It doesn’t support fake timer
• It doesn’t support fake HTTP server
• It misuses Spy and Stub
116. Stub every dependency
• Native spy feature of Jasmine is not enough
• It doesn’t support fake timer
• It doesn’t support fake HTTP server
• It misuses Spy and Stub
Sinon.js comes to rescue
118. Spy/Stub/Mock
• A test spy is a function that records arguments, return value,
the value of this and exception thrown (if any) for all its calls.
A test spy can be an anonymous function or it can wrap an
existing function.
119. Spy/Stub/Mock
• A test spy is a function that records arguments, return value,
the value of this and exception thrown (if any) for all its calls.
A test spy can be an anonymous function or it can wrap an
existing function.
• Test stubs are functions (spies) with pre-programmed
behavior. They support the full test spy API in addition to
methods which can be used to alter the stub's behavior.
120. Spy/Stub/Mock
• A test spy is a function that records arguments, return value,
the value of this and exception thrown (if any) for all its calls.
A test spy can be an anonymous function or it can wrap an
existing function.
• Test stubs are functions (spies) with pre-programmed
behavior. They support the full test spy API in addition to
methods which can be used to alter the stub's behavior.
• Mocks (and mock expectations) are fake methods (like spies)
with pre-programmed behavior (like stubs) as well as pre-
programmed expectations. A mock will fail your test if it is not
used as expected.
125. Spy
describe("when initialized", function () {
beforeEach(function() {
sinon.spy(this, "Flashcards"); create a spy for this.Flashcards
})
afterEach(function() {
this.Flashcards.restore();
})
it("should throw Error when cultureCode is not passed", function() {
try {
var flashcards = new this.Flashcards([], {
});
} catch(e) {}
expect(this.Flashcards.calledOnce()).toBeTruthy();
expect(this.Flashcards.threw()).toBeTruthy();
expect(this.Flashcards.calledWith([], {})).toBeTruthy();
});
});
126. Spy
describe("when initialized", function () {
beforeEach(function() {
sinon.spy(this, "Flashcards");
})
afterEach(function() {
this.Flashcards.restore(); unwraps the spy
})
it("should throw Error when cultureCode is not passed", function() {
try {
var flashcards = new this.Flashcards([], {
});
} catch(e) {}
expect(this.Flashcards.calledOnce()).toBeTruthy();
expect(this.Flashcards.threw()).toBeTruthy();
expect(this.Flashcards.calledWith([], {})).toBeTruthy();
});
});
127. Spy
describe("when initialized", function () {
beforeEach(function() {
sinon.spy(this, "Flashcards");
})
afterEach(function() {
this.Flashcards.restore();
})
it("should throw Error when cultureCode is not passed", function() {
try {
var flashcards = new this.Flashcards([], {
});
} catch(e) {}
expect(this.Flashcards.calledOnce()).toBeTruthy(); spy was called once
expect(this.Flashcards.threw()).toBeTruthy();
expect(this.Flashcards.calledWith([], {})).toBeTruthy();
});
});
128. Spy
describe("when initialized", function () {
beforeEach(function() {
sinon.spy(this, "Flashcards");
})
afterEach(function() {
this.Flashcards.restore();
})
it("should throw Error when cultureCode is not passed", function() {
try {
var flashcards = new this.Flashcards([], {
});
} catch(e) {}
expect(this.Flashcards.calledOnce()).toBeTruthy();
expect(this.Flashcards.threw()).toBeTruthy();
expect(this.Flashcards.calledWith([], {})).toBeTruthy();
});
});
spy threw exception at least once
129. Spy
describe("when initialized", function () {
beforeEach(function() {
sinon.spy(this, "Flashcards");
})
afterEach(function() {
this.Flashcards.restore();
})
it("should throw Error when cultureCode is not passed", function() {
try {
var flashcards = new this.Flashcards([], {
});
} catch(e) {}
expect(this.Flashcards.calledOnce()).toBeTruthy();
expect(this.Flashcards.threw()).toBeTruthy();
expect(this.Flashcards.calledWith([], {})).toBeTruthy();
});
}); spy was called at least once with
provided argument
130. Stub
describe("when update model", function () {
beforeEach(function () {
this.sync = sinon.stub(Backbone, "sync");
});
afterEach(function () { create a stub for this.Flashcards
this.sync.restore();
});
it("should put IsWordIKnow and IsWord properties at the end of url property",
function () {
this.flashcard.set('IsWordIKnow', true);
var expected_url = this.flashcard.url() + '&IsWordIKnow=' +
this.flashcard.get('IsWordIKnow') + '&IsWord=' + this.flashcard.get('IsWord');
this.flashcard.save();
expect(this.sync.getCall(0).args[2].url).toEqual(expected_url);
});
});
131. Stub
describe("when update model", function () {
beforeEach(function () {
this.sync = sinon.stub(Backbone, "sync");
});
afterEach(function () {
this.sync.restore();
});
it("should put IsWordIKnow and IsWord properties at the end of url property",
function () {
this.flashcard.set('IsWordIKnow', true);
var expected_url = this.flashcard.url() + '&IsWordIKnow=' +
this.flashcard.get('IsWordIKnow') + '&IsWord=' + this.flashcard.get('IsWord');
this.flashcard.save();
expect(this.sync.getCall(0).args[2].url).toEqual(expected_url);
});
});
save method will invoke Backbone.sync that already stubbed
132. Stub
describe("when update model", function () {
beforeEach(function () {
this.sync = sinon.stub(Backbone, "sync");
});
afterEach(function () {
this.sync.restore();
});
it("should put IsWordIKnow and IsWord properties at the end of url property",
function () {
this.flashcard.set('IsWordIKnow', true);
var expected_url = this.flashcard.url() + '&IsWordIKnow=' +
this.flashcard.get('IsWordIKnow') + '&IsWord=' + this.flashcard.get('IsWord');
this.flashcard.save();
expect(this.sync.getCall(0).args[2].url).toEqual(expected_url);
});
});
original sync method won’t be called if it was stubbed
So, no ajax request won’t be fired
133. Stub
describe("when update model", function () {
beforeEach(function () {
this.sync = sinon.stub(Backbone, "sync");
});
afterEach(function () {
this.sync.restore();
});
it("should put IsWordIKnow and IsWord properties at the end of url property",
function () {
this.flashcard.set('IsWordIKnow', true);
var expected_url = this.flashcard.url() + '&IsWordIKnow=' +
this.flashcard.get('IsWordIKnow') + '&IsWord=' + this.flashcard.get('IsWord');
this.flashcard.save();
expect(this.sync.getCall(0).args[2].url).toEqual(expected_url);
});
});
get arguments of stubbed calling (spy can also do this)
134. Stub
But, Spy cannot do like so:
it("should always confirm every confirmation", function () {
sinon.stub(window, 'confirm');
confirm.returns(true);
expect(confirm('Are you sure?')).toBeTruthy();
window.confirm.restore();
}
Makes window.confirm() return truth
135. Stub
But, Spy cannot do like so:
it("should always confirm every confirmation", function () {
sinon.stub(window, 'confirm');
confirm.returns(true);
expect(confirm('Are you sure?')).toBeTruthy();
window.confirm.restore();
}
Native confirm behavior won’t fired
136. Stub
But, Spy cannot do like so:
it("should always confirm every confirmation", function () {
sinon.stub(window, 'confirm');
confirm.returns(true);
expect(confirm('Are you sure?')).toBeTruthy();
window.confirm.restore();
}
Native confirm behavior won’t fired
It needs user interaction to finish this test without stub.
This test probably be failed if user not confirms with it.
That test case is unstable.
137. Mock
• Mock focuses on implementation details of
one method
• It utilizes upfront expectation to verify details
rather than asserting after the details
138. Mock
describe("when initialized", function () {
it("should throw Error when cultureCode is not passed", function() {
var myAPI = { method: function () {} };
var spy = sinon.spy();
var mock = sinon.mock(myAPI);
mock.expects("method").once(); expectation upfront
myAPI.method();
spy();
verify mock behavior
mock.verify();
expect(spy.calledOnce).toBeTruthy();
});
});
139. Without FakeTimers
it("should show teacher box after 1 hour", function () {
var hour = 1000 * 60 * 60;
setTimeout(showTeacherbox, hour);
waits(hour); must wait 1 hour...crazy
runs(function() {
expect($(‘#teacherbox’)).toBeVisible();
});
});
140. FakeTimers
it("should show teacher box after 1 hour", function () {
this.clock = sinon.useFakeTimers();
var hour = 1000 * 60 * 60;
create a fake timer
setTimeout(showTeacherbox, hour);
this.clock.tick(hour);
expect($(‘#teacherbox’)).toBeVisible();
this.clock.restore();
});
141. FakeTimers
it("should show teacher box after 1 hour", function () {
this.clock = sinon.useFakeTimers();
var hour = 1000 * 60 * 60;
setTimeout(showTeacherbox, hour);
tick the clock ahead 1 hour
this.clock.tick(hour);
expect($(‘#teacherbox’)).toBeVisible();
this.clock.restore();
});
142. FakeTimers
it("should show teacher box after 1 hour", function () {
this.clock = sinon.useFakeTimers();
var hour = 1000 * 60 * 60;
setTimeout(showTeacherbox, hour);
this.clock.tick(hour - 1);
expect($(‘#teacherbox’)).toBeHidden(); won’t happen
this.clock.tick(1);
expect($(‘#teacherbox’)).toBeVisible(); will happen
this.clock.restore();
});