Score 100% on the quiz to continue
Data types
The primitives (undefined, null, Boolean, Number, String) and the structural types (Array, Object, Function) every test is built out of.
Everything in a test is a piece of data. The name you type into a field, the status code that came back, the list of rows in a table, the true-or-false answer to "is this button visible?".
JavaScript sorts all of that into a small number of types. Learn the types and most of the language's surprises stop being surprises.
There are two families: primitives and structural types.
Primitives
A primitive is a single, simple value. There are five you will use constantly.
String
Text. Written between single quotes, double quotes, or backticks.
console.log('Acme Corporation')
console.log("Acme Corporation")Pick one style of quote and stay consistent. This course uses single quotes.
Number
Any number. JavaScript does not separate whole numbers from decimals: 42 and 3.14 are both just Number.
console.log(200)
console.log(19.99)👨🏫 This is why a status code and a price are the same type. It also means0.1 + 0.2gives you0.30000000000000004, which is not a JavaScript bug but how computers store decimals everywhere. Never assert on the exact result of decimal maths.
Boolean
Exactly two possible values: true and false. This is the type every assertion ultimately produces.
console.log(true)
console.log(false)undefined
The value of something that exists but was never given a value. JavaScript assigns it for you.
let statusCode
console.log(statusCode)That prints undefined. Nobody set it to anything.
null
The value of something deliberately set to "nothing". The difference from undefined matters: undefined means "nobody filled this in", null means "somebody filled this in with nothing".
const middleName = null
console.log(middleName)👨🏫 In an API response,"phone": nullmeans the field exists and the customer has no phone. A missingphonekey gives youundefinedinstead, meaning the API did not send the field at all. Those are two different bugs, so it is worth being able to tell them apart.
Structural types
A structural type holds several values, in a structure. There are three you need.
Array
An ordered list. Written with square brackets, items separated by commas. The order is preserved, and positions are numbered from zero.
const sizes = ['Small', 'Medium', 'Large']
console.log(sizes[0])
console.log(sizes[2])
console.log(sizes.length)That prints Small, then Large, then 3.
👨🏫 Counting from zero trips up everyone at the start. The first item is at index0, so the last item of a three-item array is at index2, never3. Asking forsizes[3]gives youundefined.
An array can hold anything, including other arrays and objects. In testing, an array is usually a list of rows, a list of inputs, or a list of expected values.
Object
A collection of named values. Written with curly braces, as key: value pairs.
const customer = {
name: 'Acme Corporation',
size: 'Large',
active: true,
}
console.log(customer.name)
console.log(customer.active)That prints Acme Corporation, then true.
An object is what an API response body looks like, and what a piece of test data looks like. Arrays and objects nest inside each other freely: an array of customer objects is the single most common shape you will meet.
const customers = [
{ name: 'Acme Corporation', size: 'Large' },
{ name: 'Globex', size: 'Small' },
]
console.log(customers[1].name)That prints Globex.
Function
A reusable block of code. In JavaScript a function is a value like any other, which is why it belongs in this list rather than in a chapter of its own.
function greet(name) {
return 'Hello, ' + name
}
console.log(greet('Walmyr'))That prints Hello, Walmyr.
👨🏫 The fact that a function is a value is the single most important idea in this course. It is what lets you pass a function toit(), tobeforeEach(), and toforEach(). Lesson 7 covers functions properly.
How to check a type
typeof tells you what type a value is.
console.log(typeof 'Acme')
console.log(typeof 42)
console.log(typeof true)
console.log(typeof undefined)
console.log(typeof { name: 'Acme' })
console.log(typeof [1, 2, 3])
console.log(typeof null)The last two are worth staring at. typeof [1, 2, 3] says 'object', not 'array', and typeof null also says 'object', which is a famous mistake in the language that can never be fixed without breaking the web.
To check for an array, use Array.isArray() instead.
console.log(Array.isArray([1, 2, 3]))
console.log(Array.isArray({ name: 'Acme' }))That prints true, then false.
Syntax overview 📖
typeof
Returns a string naming the type of a value.
typeof 'Acme'Array.isArray()
Returns true when the value is an array. The reliable way to check, since typeof cannot.
Array.isArray(['Small', 'Large']).length
The number of items in an array, or the number of characters in a string.
['a', 'b', 'c'].length
'Acme'.lengthAccessing values
Square brackets and a number for arrays, a dot and a name for objects.
sizes[0]
customer.nameThe testing part 🧪
Types are not academic. Here is the single most common false pass in web test automation, and it is a types problem.
Text read from a web page is always a String, even when it looks like a number.
it('shows the right total', () => {
cy.get('[data-testid="total"]').invoke('text').then((total) => {
// total is the string '42', not the number 42
expect(Number(total)).to.equal(42)
})
})Without that Number() conversion, comparing '42' with 42 using a strict check fails, and comparing them with a loose check passes for reasons you did not intend. Lesson 4 covers exactly that difference.
The second place types matter is API testing, where knowing the expected type is the test.
it('returns a well-formed customer', async ({ request }) => {
const response = await request.get('/api/customers/1')
const customer = await response.json()
expect(typeof customer.name).toBe('string')
expect(typeof customer.active).toBe('boolean')
expect(Array.isArray(customer.contacts)).toBe(true)
})That test does not care what the customer is called. It cares that name is text, active is a true-or-false, and contacts is a list. If a backend change turns active into the string 'true', every UI check might still pass while this one catches it immediately.
👨🏫 A field that changes type is one of the nastiest bugs to find later, because the value still looks right when you print it.'true'andtrueprint identically.
Suggested content 📚
- JavaScript data types and data structures - MDN
- String - MDN
- Number - MDN
- Boolean - MDN
- null - MDN
- undefined - MDN
- Array - MDN
- Object - MDN
- typeof - MDN
Exercise 🎯
Create 01-data-types.js in your fork and do the following:
- Declare one value of each primitive type: a string, a number, a boolean, an
undefined, and anull - Declare an array holding at least three strings, and print its length and its first item
- Declare an object describing a customer, with a name, a size, and whether it is active, and print two of its fields
- Print the
typeofeach of your five primitives - Print
Array.isArray()for both your array and your object
Run it with node 01-data-types.js, then commit and push it.
🙊 Here is one way to write it:
const name = 'Acme Corporation'
const employees = 240
const active = true
let notSetYet
const phone = null
const sizes = ['Small', 'Medium', 'Large']
const customer = { name: 'Acme Corporation', size: 'Large', active: true }
console.log(sizes.length)
console.log(sizes[0])
console.log(customer.name, customer.active)
console.log(typeof name, typeof employees, typeof active, typeof notSetYet, typeof phone)
console.log(Array.isArray(sizes), Array.isArray(customer))Two things to notice in the output.typeof notSetYetprintsundefinedeven though nothing was assigned. That is JavaScript filling in the blank, not an error.typeof phoneprintsobject, notnull. That is the language bug mentioned above. When you need to check fornull, compare against it directly rather than trustingtypeof.
Show the world what you learned 🌎
To show your professional network what you learned in this lesson, post the following on LinkedIn.
I started the "JavaScript for QAs" course by @Walmyr Lima e Silva Filho at the @Talking About Testing School, and the first lesson already explained a false pass I had seen before: text read off a page is always a string, even when it looks like a number, so comparing it to a number is not the check you think you wrote. #TalkingAboutTesting #TATSchool #JavaScriptForQAs #JavaScript #TestAutomation
👨🏫 Remember to tag me in your post. Here is my LinkedIn profile.
Quiz
What does `typeof [1, 2, 3]` return, and what should you use instead?
Score 100% on the quiz to continue