Back to Repositories

Testing Raung Bytecode Processing and Decompilation in skylot/jadx

This test suite implements core functionality for testing Raung file processing in the JADX decompiler. It provides essential infrastructure for loading and verifying Raung bytecode files, enabling comprehensive testing of JADX’s decompilation capabilities.

Test Coverage Overview

The test suite provides comprehensive coverage for Raung file processing and decompilation workflows.

  • Tests file loading from different directory structures
  • Handles single and multiple Raung file processing
  • Verifies class node generation and decompilation
  • Tests package and class name resolution

Implementation Analysis

The implementation follows a structured approach using JUnit for test organization. It extends IntegrationTest class to leverage common testing utilities while adding Raung-specific functionality.

  • Uses BeforeEach annotation for test initialization
  • Implements helper methods for file path resolution
  • Provides flexible API for single and multi-file testing
  • Utilizes Stream API for file collection and processing

Technical Details

  • JUnit Jupiter testing framework
  • AssertJ for assertions
  • Custom JadxAssertions for specialized checks
  • File system operations for test resource management
  • Integration with JadxInternalAccess for decompiler access
  • Configurable test directory structure (RAUNG_TESTS_PROJECT, RAUNG_TESTS_DIR)

Best Practices Demonstrated

The test suite exemplifies several testing best practices in its implementation.

  • Clear separation of concerns with dedicated methods for different testing scenarios
  • Robust error handling with descriptive assertion messages
  • Flexible and reusable test infrastructure
  • Consistent file naming and organization conventions
  • Comprehensive documentation of test methods

skylot/jadx

jadx-core/src/test/java/jadx/tests/api/RaungTest.java

            
package jadx.tests.api;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.jupiter.api.BeforeEach;

import jadx.api.JadxInternalAccess;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;

import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

public abstract class RaungTest extends IntegrationTest {

	private static final String RAUNG_TESTS_PROJECT = "jadx-core";
	private static final String RAUNG_TESTS_DIR = "src/test/raung";
	private static final String RAUNG_TESTS_EXT = ".raung";

	@BeforeEach
	public void init() {
		super.init();
		this.useJavaInput();
	}

	/**
	 * Preferred method for one file raung test
	 */
	protected ClassNode getClassNodeFromRaung() {
		String pkg = getTestPkg();
		String clsName = getTestName();
		return getClassNodeFromRaung(pkg + File.separatorChar + clsName, pkg + '.' + clsName);
	}

	protected ClassNode getClassNodeFromRaung(String file, String clsName) {
		File raungFile = getRaungFile(file);
		return getClassNodeFromFiles(Collections.singletonList(raungFile), clsName);
	}

	protected List<ClassNode> loadFromRaungFiles() {
		jadxDecompiler = loadFiles(collectRaungFiles(getTestPkg(), getTestName()));
		RootNode root = JadxInternalAccess.getRoot(jadxDecompiler);
		List<ClassNode> classes = root.getClasses(false);
		decompileAndCheck(classes);
		return classes;
	}

	private List<File> collectRaungFiles(String pkg, String testDir) {
		String raungFilesDir = pkg + File.separatorChar + testDir + File.separatorChar;
		File raungDir = getRaungDir(raungFilesDir);
		String[] raungFileNames = raungDir.list((dir, name) -> name.endsWith(".raung"));
		assertThat(raungFileNames).as("Raung files not found in " + raungDir).isNotNull();
		return Stream.of(raungFileNames)
				.map(file -> new File(raungDir, file))
				.collect(Collectors.toList());
	}

	private static File getRaungFile(String baseName) {
		File raungFile = new File(RAUNG_TESTS_DIR, baseName + RAUNG_TESTS_EXT);
		if (raungFile.exists()) {
			return raungFile;
		}
		File pathFromRoot = new File(RAUNG_TESTS_PROJECT, raungFile.getPath());
		if (pathFromRoot.exists()) {
			return pathFromRoot;
		}
		throw new AssertionError("Raung file not found: " + raungFile.getPath());
	}

	private static File getRaungDir(String baseName) {
		File raungDir = new File(RAUNG_TESTS_DIR, baseName);
		if (raungDir.exists()) {
			return raungDir;
		}
		File pathFromRoot = new File(RAUNG_TESTS_PROJECT, raungDir.getPath());
		if (pathFromRoot.exists()) {
			return pathFromRoot;
		}
		throw new AssertionError("Raung dir not found: " + raungDir.getPath());
	}
}