Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: support artifact assertions in smoke tests #8044

Merged
merged 15 commits into from
Apr 11, 2019

Conversation

mattzeunert
Copy link
Contributor

Summary

We'd like to make assertions against the artifacts in the smoke tests.

  • Wrap existing expectations in lhr top level object
  • Add support for having artifacts expectations in addition to lhr

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice @mattzeunert this was super quick turnaround! :)

const artifactAssertions = [];
if (expected.artifacts) {
Object.keys(expected.artifacts).map(artifactName => {
const actualResult = /** @type {any} */ (actual.artifacts)[artifactName];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we type these as partial artifacts? I guess it doesn't help much since we don't type check our assertions :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do artifacts have a type other than the union type of all artifact values? Is that what you were thinking of?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I get it now, we can type the artifacts key instead of it being string and then the artifact value will be the union type.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome yeah LGTM :)

actual: actual.errorCode,
expected: expected.errorCode,
equal: actual.errorCode === expected.errorCode,
actual: actual.lhr.errorCode,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that we are fixing things, this isn't really in the LHR, so makes sense to move out at top level

args.push('-GA');
}
// Save artifacts
args.push('-GA');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should specify a tmp path if we're always doing this otherwise every smoke run will overwrite the users saved artifacts

@patrickhulce
Copy link
Collaborator

For other reviewers ?w=1 was a lifesaver here, it's really only ~100 or so line change without the whitespace diffs :)

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

errorCode: Comparison;
finalUrl: Comparison;
}

export interface Assertion{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: space after Assertion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, realized this is the same as Smokehouse.Comparison.


return {
audits: collatedAudits,
assertions,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit strange that we separate out the others but mix these into assertions IMO, I might prefer a separate artifacts property or just collapsing everything into a comparison array

but not a huge deal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged to just return a Comparison array.

@mattzeunert
Copy link
Contributor Author

@brendankenny What do you think about this?

@brendankenny
Copy link
Member

I only got to take a cursory read yesterday with the 4.3 stuff going on, but the concept and implementation were looking great to me. I'll take a closer look later today.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good, this is a definite improvement!

* @param {string} name
* @param {any} actualResult
* @param {any} expectedResult
* @returns {Smokehouse.Comparison}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@return to match the file

@@ -102,47 +102,76 @@ function findDifference(path, actual, expected) {
return null;
}

/**
* @param {string} name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you give a doc string for name, not obvious from outside what it is.

and should it be the last param? Total nit since this is entirely internal, but usually for assertion libraries the string description is the last param, though admittedly this string is slightly different

Also, reading it now, I really regret that we called that property category in the return object :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually for assertion libraries the string description is the last param

though findDifference isn't like that and I'm pretty sure I wrote its signature, so what do I know :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed category to name now. We also use it for difference at TapTargets artifact.length, so it's more of an object name than a custom error message you'd have for an assertion. If we compare the whole runner result we could just use the key path here maybe.

args.push('-GA');
}
// Save artifacts
args.push(`-GA=${artifactsDirectory}`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is always done, can just move these two lines into the args array declaration up above

lighthouse-cli/test/smokehouse/smokehouse.js Outdated Show resolved Hide resolved
audits: Comparison[];
errorCode: Comparison;
finalUrl: Comparison;
export type ExpectedRunResult = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we call basically this type on the LH side RunnerResult, so should this be ExpectedRunnerResult?

* @param {any} expectedResult
* @returns {Smokehouse.Comparison}
*/
function makeAssertion(name, actualResult, expectedResult) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe call this makeComparison now?

diff,
};
}

/**
* Collate results into comparisons of actual and expected scores on each audit.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should update the "on each audit" part

});
/** @type {Smokehouse.Comparison[]} */
let auditAssertions = [];
if (expected.lhr.audits) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we require audits to be defined, fwiw

@brendankenny
Copy link
Member

brendankenny commented Apr 9, 2019

I'd like to go all the way and use the real types for the LH.RunnerResult (using a recursive Partial<> except for the few things which are in the Pick<> type today), which after this PR would mostly just need testing lhr.runtimeError instead of our constructed errorCode (though we could still test that too). We could do that in another PR if others are ok with the idea.

throw new Error(`Config run did not generate artifact ${artifactName}`);
}

const expectedResult = (expected.artifacts || {})[artifactName];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be able to nuke this || given the if on line 132

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, TS fails without the || {} if the artifacts are accessed in the map callback. In general constraining the type seems to work in nested functions, but not here somehow...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right the TS callback problem, my preferred way around this recently has been to assign expected.artifacts to a variable right after we've asserted its definedness, then when you access it in the closure TS already knows it's safe

[results.finalUrl, results.errorCode, ...results.audits].forEach(auditAssertion => {
if (auditAssertion.equal) {
comparisons.forEach(assertion => {
if (assertion.equal) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like we've still got quite a bit of assertion/comparison mixing going on throughout but that was preexisting :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like it should always be comparison? Assertion seems more narrow in scope to me than what we have here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed :) cleanup for another time

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💥

@brendankenny
Copy link
Member

I really don't understand the lint issue here. They aren't inconsistently quoted, and I can't get the failure in a completely fresh download and install of the lighthouse repo

@brendankenny
Copy link
Member

welllll, I'm going to override travis again, assuming that when this is merged back into master everything will be happy. We'll see how this goes for the second time this week :)

@brendankenny brendankenny merged commit 9faf2ff into master Apr 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants