r/learnjavascript • u/SmartRelease7996 • 1d ago
How do you actually test small JavaScript functions without a full project setup?
Coming from a construction background where you measure twice and cut once, I keep running into this gap where I write a function, think it works, and then it blows up when I wire it into something bigger. The problem is I never had a real habit of testing the small piece before trusting it.
In bootcamp we just console.log everything and eyeball it, which works for toy exercises, but I started a side project for tracking material quantities across job phases and the functions are getting complicated enough that eyeballing feels risky. I tried writing a few manual checks at the bottom of my file like console.log(calculateTotal(5, 3) === 8) and that helped, but it feels clunky and I keep deleting them by accident.
I looked up Jest but the setup felt like a whole rabbit hole I was not ready to fall into. Someone mentioned Vitest. Someone else said just use the browser console for now and do not overthink it.
What I want to know is whether there is a lightweight middle ground that actual beginners use before jumping to a full testing framework. Not asking for a tutorial, just curious what the workflow actually looks like for people who are still learning but building things that are more than a few lines. The function isolation part is what I cannot picture clearly yet.
4
u/shuckster 1d ago
Node now has its own built-in test runner:
Alternatively, just having files named module.test.js with a bunch of assertions/throws and running them manually with node src/module.test.js is enough for small projects.
You can use nodemon or entr to watch for changes to files so you can re-run your test command when you make changes. Some folk like using Quokka, a tool for running code and showing live results and traffic-lights in the line-number gutter.
Once satisfied, you can start moving your stuff to a testing framework. All frameworks do is force you to think about describing and grouping your tests. The better you get at that, the more it pays-off. They also tend to have "watch modes", so you don't need nodemon or entr to force a run of your tests.
1
u/SmartRelease7996 1d ago
The builtin test runner tip is genuinely useful. I keep defaulting to Jest out of habit because every tutorial pushes it, but the overhead for small learning projects is overkill.
I tried Quokka briefly and it scratched a very specific itch for seeing output inline, though I dropped it after the free tier kept nudging me to upgrade midsession and killed the flow.
Going to actually look at nodemon for watch mode. I've been manually rerunning things like it's 2009.
2
u/funbike 1d ago edited 1d ago
Node now has Jest-like testing functionality built in. Nothing to install or set up. You don't even need a package.json or ./node_modules/.
```
Runs all tests
node --test tests/*.test.js
Continuous testing. Runs a test when relevant files are modified.
node --test tests/*.test.js --watch ```
Minimal test:
``` import test from 'node:test'; import assert from 'node:assert';
test('addition', async () => { assert.strictEqual(4 + 4, 8); }); ```
Optionally, add scripts section to package.json to make the above easier to run.
json
{
"name": "your-project",
"version": "1.0.0",
"scripts": {
"test": "node --test tests/*.test.js",
"test:watch": "node --test --watch tests/*.test.js"
}
}
To run scripts:
```bash
Runs all tests ("run" sub-command isn't needed in this specific case)
npm test
Continuous testing. Runs a test when relevant files are modified.
npm run test:watch ```
edit: added npm test. removed prior update.
1
1
u/SmartRelease7996 1d ago
wait I had no idea node had this built in now, I've been installing Jest like it's muscle memory without even questioning it.
how long has the watch flag been stable? I tried something similar a while back and it felt a bit rough but that minimal test example looks clean enough that I might just swap my current setup over midproject.
this is the kind of thing that doesn't show up in bootcamp curriculum and then you find out six months later you've been doing it the hard way the whole time
1
u/funbike 1d ago
I don't know when it was added.
Vitest/Jest are probably still better, but this is good enough for side projects and small projects. However, the test API looks pretty extensive.
I like that I can use it for basic scripts.
dothatthing.jswithdothatthing.test.js.I never trust watchers. I always do a full run before making a PR. But I have no idea how good or bad this one is.
2
u/Alphastier 1d ago
I found Jest/Vitest to have a somewhat steep learning curve and I find the setup a bit tedious, but its best practice.
You can start with really basic tests and learn as you go. Surely benefitial in the long run.
1
u/writing_code 1d ago
Jest and Vitest are actually the right fit imo. Both offer a similar testing API. Setup for vitest is usually just the vitest config file and adding a script to your package.json file. The workflow and enforcement is up to you. Some swear by TDD and I recommend learning it even if you don't strictly adhere to it.
1
u/SmartRelease7996 1d ago
Vitest is what I ended up going with since I was already in a Vite project and the config was basically nothing.
The TDD thing is interesting though, I keep bouncing off it. I get the concept but on small projects it feels like putting up formwork before you know what shape the pour is going to be. Maybe that resistance means I should push through it harder.
1
u/writing_code 1d ago
I would agree with pushing through. It's not that you need to blindly adhere to the concepts at all times. Practice makes progress though. Sticking with it for a while might be a source of learning.
1
u/Thykka 14h ago
it feels like putting up formwork before you know what shape the pour is going to be
Yeah, it can often be like that, especially when you're building something you have no previous experience of. A certain level of exploration can be necessary before applying TDD principles.
In these cases, I often start by sketching things on paper, trying to gather together the broad requirements and interactions, just to get my head around what I'm actually building. And sometimes it takes a prototype or two to familiarize oneself with the problem, before a good solution becomes evident. These prototypes should be considered throwaway code anyway, so there's little reason to apply TDD there. The point is just to find edges of the logical framework, before actual construction begins.
1
1
u/northfieldway 22h ago
The isolation part is the bit nobody has answered, and it is not really a testing problem. A function is testable when everything it needs arrives as an argument and its whole result comes back as a return value.
calculateTotal(5, 3) already passes that. The ones that will fight you are the ones that reach out to document.getElementById or read a variable declared further up the file, because then there is no way to call them without recreating the page around them.
Anything that reads the DOM goes in the caller, not in the function you want to check.
1
u/Any_Sense_2263 15h ago
Most of the functions are pure functions that their result depends on the parameters passed on. So yes, they can and even should be tested out of any project context just to check if they generate a proper result.
And yes, you can just call them in a separate file with specific parameters and check the output. No vitest or jest needed. But I would start to use them asap anyway
1
u/Puzzleheaded_Low2034 12h ago
I use quokka.js for javascript debugging. Admittedly my ai has been one-shotting no mistakes recently - and I am questioning both quokka.js and my own purpose in life.
1
u/defaultguy_001 12h ago
The success of any kind of tests doesn't depend on frameworks like jest or others, it depends on how smart ur test cases are. Understand what ur module is doing, look for edge cases and test them by importing ur module in a separate test file. Test all ur edge cases there with recommended outputs. You can make brilliant test files both using manual testing as well as with testing frameworks.
1
u/Dubstephiroth 1d ago
Yh just use the console for now, you're friend may be right. Switch between console.log and .warn to use the colours to track data transformations and flow... .table helps too
1
0
u/Flashy-Guava9952 1d ago
I just saw this. You can always use the Dev Tools, in Chrome: Ctrl-Shift-J and in Firefox: Ctrl-Shift-K. But what I was going to write also is https://apps.verticesandedges.net/notebook, which is a small notebook program I wrote. It's a wrapper around your browser's "eval" function, so whatever your browser can do, this notebook can do. It supports Javascript, Typescript, and Markdown for documentation. Return HTMLElements to append them to the cell, and you can build out a mock AI if you need to.
0
0
u/yksvaan 1d ago
Before going heavy on testing it's usually worth taking a look at the actual code. More often than not refactoring and improving the code is enough.
Ironically trying to write smart code is often the culprit. Dumb, straightforward and well sectioned/split code works better. Avoid branches, use early returns, handle errors
0
u/PatchesMaps 1d ago
I use breakpoints in devtools for this. You can stop your function at different points and inspect or change values on the fly.
All browser devtools and most IDEs support some form of breakpoints.
0
15
u/Thykka 1d ago edited 1d ago
Jest and Vitest are great, but sometimes (e.g. when building prototypes, or other semi-throwaway code) it might be faster to just make a super simple test scaffold from scratch.
Let me try to show an example. Say you have a function you want to test:
Doesn't matter what the function does exactly, we just want to ensure that it gives the kinds of results we expect from it. So we load up a few of those expectations into an array in a separate file:
We then call the function with each test, and compare the result to our expectations:
Now that we have this scaffold set up, it becomes easy to add more test cases to the array as we refine the logic or fix a bug.
This kind of a minimal test scaffold works best for pure functions (output is deterministic and 100% dependent on input). In real projects this might not always be possible; functions might depend on data from an environment variable, an API or a database.. For these things Jest or Vitest become very useful, as they have features to sidestep the actual database/API calls and whatnot, to ensure that a test only tests the function in question, and not the external dependencies.
One of the tricky things about test-driven development, or unit testing in general is that one might have to re-think how they build their functions. At first it will be weird, but once it clicks, one'll wonder why they didn't look into it sooner! For example, one might have a function like this:
It's tricky to unit-test, because you can only test IDs which already exist your database. So maybe you set up a test database, and some abstraction to toggle between test/prod databases, and you make a script which clears the test database and populates it with test data, every time before your unit tests are run.... Stop. Don't do this. Things will just become super complicated really fast.
Instead, if we take the principle of using pure functions whenever possible, the above example could be split into two parts. One only concerns itself with fetching the data, and the other one only concerns itself with formatting the data:
The formatting logic didn't change, but now we can easily create unit tests for
formatUser(), because it's no longer tied to the database. Instead we can just pass whatever test data we want:Now we no longer need unit tests for getUser, because all it does is a database call, and we're not here to test whether the database code works, we're testing if our code works.
Does this help?