SearcharxivSearch

arXiv subjects

Saba Alimadadi

Publications and source records attributed to Saba Alimadadi.

6 recordsLinked to original sources

Characterizing Structural Testability in JavaScript: An Empirical Study

Software testability has long been recognized as a software quality attribute that influences testing effort and effectiveness. While prior work has extensively studied testability in object-oriented and concurrent software, comparatively little is known about structural testability in modern JavaScript systems. JavaScript applications rely on asynchronous execution, event-driven control flow, closures, and dynamic interactions that are not explicitly captured by existing testability frameworks. This paper presents a large-scale empirical study of structural testability in JavaScript. We operationalize structural testability as a seven-dimensional construct capturing controllability, observability, branching complexity, asynchronous coordination, event-driven behaviour, encapsulation, and side-effect intensity. These dimensions are derived from AST-based static analysis and aggregated into a Composite Testability Score (CTS) for comparative analysis across functions, files, and projects. We apply this framework to 30 open-source JavaScript projects spanning diverse domains and sizes. Our analysis characterizes the distribution of structural testability, identifies recurring structural archetypes among low-CTS functions, and examines associations between project characteristics and testability. We find that structurally-challenging functions are concentrated within a relatively small subset of files and arise through multiple recurring structural configurations rather than a single dominant pattern. These findings provide new insight into structural testability in JavaScript and establish a foundation for future research on testing effort, automated test generation, testability-aware refactoring, and software quality assessment.

cs.SE

Change Impact Recommendation for JavaScript: Lessons from History and Runtime Analysis

Understanding the downstream effects of code changes is essential for software maintenance, debugging, and regression testing. This task is particularly challenging for JavaScript applications, where dynamic language features such as callbacks, events, asynchronous execution, and shared mutable state make dependencies difficult to infer precisely. Existing change impact recommendation approaches rely primarily on either dependency-based analysis or repository mining. Dependency-based techniques, particularly dynamic analysis, capture runtime interactions from observed execution but may miss relationships not exercised during analysis. In contrast, history-based techniques uncover evolutionary coupling from past changes but often introduce imprecise recommendations due to noisy co-change patterns. To investigate the strengths and limitations of these approaches in JavaScript, we engineer and evaluate three recommendation techniques: a history-based approach using co-change pattern mining, a dynamic dependency-based approach, and a hybrid approach combining both signals. We implement these techniques in a unified framework, Caprese, and evaluate them on 10 open-source Node.js applications using expert-curated reference inspection sets. Our results reveal low overlap between candidates identified by history-based and dynamic analyses, with only 22% overlap at broader inspection budgets, indicating that the two approaches capture complementary impact signals. Dynamic analysis generally yields higher precision, while history-based analysis identifies additional relevant candidates missed by dependency analysis. These findings suggest that practical change impact recommendation in JavaScript benefits from combining runtime and evolutionary signals, as no single technique sufficiently captures all relevant inspection candidates.

cs.SE

From Logic to Toolchains: An Empirical Study of Bugs in the TypeScript Ecosystem

TypeScript has rapidly become a popular language for modern web development, yet its effect on software faults remains poorly understood. This paper presents the first large-scale empirical study of bugs in real-world TypeScript projects. We analyze 633 bug reports from 16 popular open-source repositories to construct a taxonomy of fault types, quantify their prevalence, and relate them to project characteristics such as size, domain, and dependency composition. Our results reveal a fault landscape dominated not by logic or syntax errors but by tooling and configuration faults, API misuses, and asynchronous error-handling issues. We show that these categories correlate strongly with build complexity and dependency heterogeneity, indicating that modern failures often arise at integration and orchestration boundaries rather than within algorithmic logic. A longitudinal comparison with JavaScript studies shows that while static typing in TypeScript has reduced traditional runtime and type errors, it has shifted fragility toward build systems and toolchains. These findings offer new insight into how language design and ecosystem evolution reshape the fault profiles of large-scale software systems.

cs.SE

Hybrid Fault-Driven Mutation Testing for Python

Mutation testing is an effective technique for assessing the effectiveness of test suites by systematically injecting artificial faults into programs. However, existing mutation testing techniques fall short in capturing many types of common faults in dynamically typed languages like Python. In this paper, we introduce a novel set of seven mutation operators that are inspired by prevalent anti-patterns in Python programs, designed to complement the existing general-purpose operators and broaden the spectrum of simulated faults. We propose a mutation testing technique that utilizes a hybrid of static and dynamic analyses to mutate Python programs based on these operators while minimizing equivalent mutants. We implement our approach in a tool called PyTation and evaluate it on 13 open-source Python applications. Our results show that PyTation generates mutants that complement those from general-purpose tools, exhibiting distinct behaviour under test execution and uncovering inadequacies in high-coverage test suites. We further demonstrate that PyTation produces a high proportion of unique mutants, a low cross-kill rate, and a low test overlap ratio relative to baseline tools, highlighting its novel fault model. PyTation also incurs few equivalent mutants, aided by dynamic analysis heuristics.

cs.SE

A Study of Vulnerability Repair in JavaScript Programs with Large Language Models

In recent years, JavaScript has become the most widely used programming language, especially in web development. However, writing secure JavaScript code is not trivial, and programmers often make mistakes that lead to security vulnerabilities in web applications. Large Language Models (LLMs) have demonstrated substantial advancements across multiple domains, and their evolving capabilities indicate their potential for automatic code generation based on a required specification, including automatic bug fixing. In this study, we explore the accuracy of LLMs, namely ChatGPT and Bard, in finding and fixing security vulnerabilities in JavaScript programs. We also investigate the impact of context in a prompt on directing LLMs to produce a correct patch of vulnerable JavaScript code. Our experiments on real-world software vulnerabilities show that while LLMs are promising in automatic program repair of JavaScript code, achieving a correct bug fix often requires an appropriate amount of context in the prompt.

cs.CR

Stubbifier: Debloating Dynamic Server-Side JavaScript Applications

JavaScript is an increasingly popular language for server-side development, thanks in part to the Node.js runtime environment and its vast ecosystem of modules. With the Node.js package manager npm, users are able to easily include external modules as dependencies in their projects. However, npm installs modules with all of their functionality, even if only a fraction is needed, which causes an undue increase in code size. Eliminating this unused functionality from distributions is desirable, but the sound analysis required to find unused code is difficult due to JavaScript's extreme dynamicity. We present a fully automatic technique that identifies unused code by constructing static or dynamic call graphs from the application's tests, and replacing code deemed unreachable with either file- or function-level stubs. If a stub is called, it will fetch and execute the original code on-demand, thus relaxing the requirement that the call graph be sound. The technique also provides an optional guarded execution mode to guard application against injection vulnerabilities in untested code that resulted from stub expansion. This technique is implemented in an open source tool called Stubbifier, which supports the ECMAScript 2019 standard. In an empirical evaluation on 15 Node.js applications and 75 clients of these applications, Stubbifier reduced application size by 56% on average while incurring only minor performance overhead. The evaluation also shows that Stubbifier's guarded execution mode is capable of preventing several known injection vulnerabilities that are manifested in stubbed-out code. Finally, Stubbifier can work alongside bundlers, popular JavaScript tools for bundling an application with its dependencies. For the considered subject applications, we measured an average size reduction of 37% in bundled distributions.

cs.SE