-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
test: more meaningful AnimatedNumber component test #8309
base: main
Are you sure you want to change the base?
Conversation
fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); | ||
|
||
try { | ||
fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The onLayout on non-animation-number
view is not being triggered since it's no longer there. Even though we're using the same NUMBER_HEIGHT, the point is, it will not update to any number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised that the RN version of Testing Library doesn't automatically fire onLayout
events
let translateY = -1; | ||
|
||
// every digit will have a row of 10 numbers, so the translateY should be the height of the number * the number * -1 (since the animation is going up) | ||
await waitFor(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I need a waitFor() anymore since I'm using a Promise.all() afterwards to make sure all the numbers are correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on this @rahimrahman 💯
Left a couple of comments, but nothing blocking.
// jest.mock('../../../node_modules/react-native/Libraries/Text/Text', () => { | ||
// const Text = jest.requireActual('../../../node_modules/react-native/Libraries/Text/Text'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to stay commented out? If so, could we leave a comment explaining its purpose?
expect(animatedView).toBeTruthy(); | ||
}); | ||
|
||
describe.each([1, 23, 579, -123, 6789, 23456])('should show the correct number of animated views based on the digits', (animateToNumber: number) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more of a general question, but ideally, I'd like to find consistency in how we identify test cases, and in this specific instance, it seems like there's some pattern here (testing numbers with increasing digits + negative case).
I wonder whether some fuzz testing could be valuable in such cases rather than arbitrarily choosing some values. I don't have an answer here; I'm just curious to hear more thoughts.
} catch (e) { | ||
expect(e).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for not using the .rejects.toThrow('error');
pattern in here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few questions and one request for a helper method, but I definitely like the way this looks compared to the older version even for a more complicated component like this one
describe('AnimatedNumber', () => { | ||
// running on jest, since Animated is a native module, Animated.timing.start needs to be mocked in order to update to the final Animated.Value. | ||
// Ex: 1 => 2, the Animated.Value should be -20 (from -10) after the animation is done | ||
jest.spyOn(Animated, 'timing').mockImplementation((a, b) => ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we likely to need this when testing other components? I wonder if we might want to mock this globally be adding it to test/setup.ts
it('should render the non-animated number', () => { | ||
const {getByTestId} = render(<AnimatedNumber animateToNumber={123}/>); | ||
|
||
const text = getByTestId('no-animation-number'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On web, I've been recommending people to get elements with methods like screen.getByLabelText
instead of getByTestId
since it uses the accessible text. Is there an equivalent on mobile?
From what I understand, our accessibility support on mobile is pretty bad so I wouldn't be surprised if there's an option but not one that we can use
}); | ||
|
||
describe.each([1, 23, 579, -123, 6789, 23456])('should show the correct number of animated views based on the digits', (animateToNumber: number) => { | ||
it(`should display ${animateToNumber.toString().length} view(s) for ${animateToNumber}`, async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to replace any occurrences of X.toString().length
with a helper method like countDigits(X)
since it took me a minute to remember what that did. Giving it a name would help make it clearer what we're trying to do with it.
On my first read of this, I thought this meant that it made animateToNumber
views, and I was going to comment on how that would cause problems when there 😅
fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); | ||
|
||
try { | ||
fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised that the RN version of Testing Library doesn't automatically fire onLayout
events
@rahimrahman Maybe I am missing something, but aren't we missing the snapshots on the PR? I am surprised the CI did not yell about that. Maybe something we should look into. |
Summary
This was presented during Developer Meeting October 30th. The goal was to ask developers to re-consider the use of toMatchSnapshot which doesn't really give enough information what the component AnimatedNumber is doing and why it's rendering the way it did.
In order to get coverage % when running this test, you'd have to temporarily update the jest.config.js file:
Ticket Link
Checklist
E2E iOS tests for PR
.Device Information
This PR was tested on:
Screenshots
Release Note