読者です 読者をやめる 読者になる 読者になる

JUnit Plug-in での起動を調べる その 2

さて、JUnit Plug-in の続きです。

もう一度 launch メソッドを参照しておきます。

	public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor pm) throws CoreException {		
		IType[] testTypes = getTestTypes(configuration, pm);
		IVMInstall install= getVMInstall(configuration);
		IVMRunner runner = install.getVMRunner(mode);
		if (runner == null) {
			abort(MessageFormat.format(JUnitMessages.JUnitBaseLaunchConfiguration_error_novmrunner, new String[]{install.getId()}), null, IJavaLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST); 
		}
		
		int port= SocketUtil.findFreePort();
		VMRunnerConfiguration runConfig= launchTypes(configuration, mode, testTypes, port);
		setDefaultSourceLocator(launch, configuration);
		
		launch.setAttribute(PORT_ATTR, Integer.toString(port));
		launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier());
		runner.run(runConfig, launch, pm);		
	}

はじめの IType って何なんでしょうね? Javadoc 見てもよく分かりません。こんなときは、実際に使っているコードを見てみましょう。というわけで getTestType メソッドです。

	protected IType[] getTestTypes(ILaunchConfiguration configuration, IProgressMonitor pm) throws CoreException {
		IJavaProject javaProject= getJavaProject(configuration);
		if ((javaProject == null) || !javaProject.exists()) {
			abort(JUnitMessages.JUnitBaseLaunchConfiguration_error_invalidproject, null, IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT); 
		}
		if (!TestSearchEngine.hasTestCaseType(javaProject)) {
			abort(JUnitMessages.JUnitBaseLaunchConfiguration_error_junitnotonpath, null, IJUnitStatusConstants.ERR_JUNIT_NOT_ON_PATH);
		}
		IType[] testTypes = getTestTypes(configuration, javaProject, pm);
		if (testTypes.length == 0) {
			abort(JUnitMessages.JUnitBaseLaunchConfiguration_error_notests, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); 
		}
		return testTypes;
	}

ここでは IJavaProject オブジェクトを取得して、値チェックをした後にもう 1 度 getTestTypes メソッドをコールしているだけのようですね。

それでも、AbstractJavaLaunchConfigurationDelegate クラスには IJavaProject オブジェクトを取得するための getJavaProject メソッドというのがあるということが分かっただけでも収穫です。

もう 1 つの getTestTypes メソッドは

	public IType[] getTestTypes(ILaunchConfiguration configuration, IJavaProject javaProject, IProgressMonitor pm) throws CoreException {
		String testTypeName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)null);
		testTypeName= VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(testTypeName);

		if (pm == null)
			pm= new NullProgressMonitor();
		
		String containerHandle = configuration.getAttribute(LAUNCH_CONTAINER_ATTR, ""); //$NON-NLS-1$
		if (containerHandle.length() == 0) {
			return findSingleTest(javaProject, testTypeName);
		}
		return findTestsInContainer(containerHandle, pm);
	}

ILaunchConfiguration オブジェクトからはいろいろとアトリビュートが取得できることは分かっていたのですが、実際にどういうものが入っているのかは、いまいち分かりませんでした。でも、こうやって実例を見ると分かりますね。

IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME というのがメインのクラスの名前に対応するキーなのでしょうか。実際にやってみましょう。

WrpeLaunchConfigurationDelegate#launch メソッドを次のようにしてみました。

    public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
        String testTypeName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)null);
        System.out.println("TestTypeName: " + testTypeName);
    }

実行すると

TestTypeName: SimpleBox

と表示されました。やはり、起動するクラスの名前が入っているようです。起動するクラスを Test に変更して見ると、ちゃんと

TestTypeName: Test

と表示されるので、間違いないでしょう。これで、起動するクラスを取得することはできました。

さて、話は戻って IType です。JUnitBaseLaunchConfiguration#getTestTypes メソッドを追っていくと findSingleTest メソッドをコールしています。findSingleTest メソッドでは findType メソッドをコールしているようです。

	private IType findType(IJavaProject javaProject, String mainTypeName) throws JavaModelException {
		return javaProject.findType(mainTypeName);
	}

これも WrpeLaunchConfigurationDelegate#launch メソッドに組み込んで試してみます。

    public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
        String testTypeName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)null);
        System.out.println("TestTypeName: " + testTypeName);

        IJavaProject javaProject= getJavaProject(configuration);
        IType type = javaProject.findType(testTypeName);
        System.out.println("Type: " + type);
    }

さて、実行してみると (起動するクラスは SimpleBox クラスに戻してあります)

TestTypeName: SimpleBox
Type: class SimpleBox [in [Working copy] SimpleBox.java [in <default> [in <project root> [in sample]]]]
  SimpleBox()
  static void main(String[])

起動クラス SimpleBox の情報がいろいろと表示されました。さて、このような情報が取得できるようになったのは分かりましたが、それをどういう風に使うのでしょう。それには再び JUnitBaseLaunchConfiguration#launch メソッドに戻って調べる必要があるようです。