2021-01-29 00:20:46 +05:30
---
stage: none
group: unassigned
2022-11-25 23:54:43 +05:30
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
2021-01-29 00:20:46 +05:30
---
2020-04-22 19:07:51 +05:30
# Refactoring guide
This document is a collection of techniques and best practices to consider while performing a refactor.
## Pinning tests
Pinning tests help you ensure that you don't unintentionally change the output or behavior of the entity you're refactoring. This even includes preserving any existing *buggy* behavior, since consumers may rely on those bugs implicitly.
### Example steps
2021-09-30 23:02:18 +05:30
1. Identify all the possible inputs to the refactor subject (for example, anything that's injected into the template or used in a conditional).
2020-04-22 19:07:51 +05:30
1. For each possible input, identify the significant possible values.
1. Create a test to save a full detailed snapshot for each helpful combination values per input. This should guarantee that we have "pinned down" the current behavior. The snapshot could be literally a screenshot, a dump of HTML, or even an ordered list of debugging statements.
1. Run all the pinning tests against the code, before you start refactoring (Oracle)
2022-11-25 23:54:43 +05:30
1. Perform the refactor (or check out the commit with the work done)
2020-04-22 19:07:51 +05:30
1. Run again all the pinning test against the post refactor code (Pin)
1. Compare the Oracle with the Pin. If the Pin is different, you know the refactoring doesn't preserve existing behavior.
1. Repeat the previous three steps as necessary until the refactoring is complete.
### Example commit history
2022-11-25 23:54:43 +05:30
Leaving in the commits for adding and removing pins helps others check out and verify the result of the test.
2020-04-22 19:07:51 +05:30
2020-06-23 00:09:42 +05:30
```shell
2020-04-22 19:07:51 +05:30
AAAAAA Add pinning tests to funky_foo
BBBBBB Refactor funky_foo into nice_foo
CCCCCC Remove pinning tests for funky_foo
```
Then you can leave a reviewer instructions on how to run the pinning test in your MR. Example:
> First revert the commit which removes the pin.
>
2020-06-23 00:09:42 +05:30
> ```shell
2020-04-22 19:07:51 +05:30
> git revert --no-commit $(git log -1 --grep="Remove pinning test for funky_foo" --pretty=format:"%H")
> ```
>
> Then run the test
>
2020-06-23 00:09:42 +05:30
> ```shell
2020-04-22 19:07:51 +05:30
> yarn run jest path/to/funky_foo_pin_spec.js
> ```
### Try to keep pins green
It's hard for a refactor to be 100% pure. This means that a pin which captures absolutely everything is bound to fail with
some trivial and expected differences. Try to keep the pins green by cleaning the pin with the expected changes. This helps
others quickly verify that a refactor was safe.
[Example ](https://gitlab.com/gitlab-org/gitlab/-/commit/7b73da4078a60cf18f5c10c712c66c302174f506?merge_request_iid=29528#a061e6835fd577ccf6802c8a476f4e9d47466d16_0_23 ):
```javascript
// funky_foo_pin_spec.js
const cleanForSnapshot = el => {
Array.from(rootEl.querySelectorAll('[data-deprecated-attribute]')).forEach(el => {
el.removeAttribute('data-deprecated-attribute');
});
};
// ...
expect(cleanForSnapshot(wrapper.element)).toMatchSnapshot();
```
### Resources
2022-07-23 23:45:48 +05:30
[Unofficial wiki explanation ](https://wiki.c2.com/?PinningTests )
2020-04-22 19:07:51 +05:30
### Examples
2020-06-23 00:09:42 +05:30
- [Pinning test in a Haml to Vue refactor ](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27691#pinning-tests )
2020-04-22 19:07:51 +05:30
- [Pinning test in isolating a bug ](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/32198#note_212736225 )
2022-11-25 23:54:43 +05:30
- [Pinning test in refactoring dropdown list ](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28173 )
2020-04-22 19:07:51 +05:30
- [Pinning test in refactoring vulnerability_details.vue ](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25830/commits )
- [Pinning test in refactoring notes_award_list.vue ](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29528#pinning-test )
2021-03-11 19:13:27 +05:30
- < i class = "fa fa-youtube-play youtube" aria-hidden = "true" ></ i > [Video of pair programming session on pinning tests ](https://youtu.be/LrakPcspBK4 )